(root)/
gcc-13.2.0/
libffi/
src/
powerpc/
ffi_sysv.c
       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, fpr_count = 0, gpr_count = 0, stack_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        gpr_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  	  if (fpr_count >= NUM_FPR_ARG_REGISTERS - 1)
     186  	    {
     187  	      fpr_count = NUM_FPR_ARG_REGISTERS;
     188  	      /* 8-byte align long doubles.  */
     189  	      stack_count += stack_count & 1;
     190  	      stack_count += 4;
     191  	    }
     192  	  else
     193  	    fpr_count += 2;
     194  #ifdef __NO_FPRS__
     195  	  return FFI_BAD_ABI;
     196  #endif
     197  	  break;
     198  #endif
     199  
     200  	case FFI_TYPE_DOUBLE:
     201  	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)
     202  	    {
     203  	      /* 8-byte align doubles.  */
     204  	      stack_count += stack_count & 1;
     205  	      stack_count += 2;
     206  	    }
     207  	  else
     208  	    fpr_count += 1;
     209  #ifdef __NO_FPRS__
     210  	  return FFI_BAD_ABI;
     211  #endif
     212  	  break;
     213  
     214  	case FFI_TYPE_FLOAT:
     215  	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)
     216  	    /* Yes, we don't follow the ABI, but neither does gcc.  */
     217  	    stack_count += 1;
     218  	  else
     219  	    fpr_count += 1;
     220  #ifdef __NO_FPRS__
     221  	  return FFI_BAD_ABI;
     222  #endif
     223  	  break;
     224  
     225  	case FFI_TYPE_UINT128:
     226  	  /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set
     227  	     of four consecutive gprs. If we do not have enough, we
     228  	     have to adjust the gpr_count value.  */
     229  	  if (gpr_count >= NUM_GPR_ARG_REGISTERS - 3)
     230  	    gpr_count = NUM_GPR_ARG_REGISTERS;
     231  	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
     232  	    stack_count += 4;
     233  	  else
     234  	    gpr_count += 4;
     235  	  break;
     236  
     237  	case FFI_TYPE_UINT64:
     238  	case FFI_TYPE_SINT64:
     239  	  /* 'long long' arguments are passed as two words, but
     240  	     either both words must fit in registers or both go
     241  	     on the stack.  If they go on the stack, they must
     242  	     be 8-byte-aligned.
     243  
     244  	     Also, only certain register pairs can be used for
     245  	     passing long long int -- specifically (r3,r4), (r5,r6),
     246  	     (r7,r8), (r9,r10).  */
     247  	  gpr_count += gpr_count & 1;
     248  	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
     249  	    {
     250  	      stack_count += stack_count & 1;
     251  	      stack_count += 2;
     252  	    }
     253  	  else
     254  	    gpr_count += 2;
     255  	  break;
     256  
     257  	case FFI_TYPE_STRUCT:
     258  	  /* We must allocate space for a copy of these to enforce
     259  	     pass-by-value.  Pad the space up to a multiple of 16
     260  	     bytes (the maximum alignment required for anything under
     261  	     the SYSV ABI).  */
     262  	  struct_copy_size += ((*ptr)->size + 15) & ~0xF;
     263  	  /* Fall through (allocate space for the pointer).  */
     264  
     265  	case FFI_TYPE_POINTER:
     266  	case FFI_TYPE_INT:
     267  	case FFI_TYPE_UINT32:
     268  	case FFI_TYPE_SINT32:
     269  	case FFI_TYPE_UINT16:
     270  	case FFI_TYPE_SINT16:
     271  	case FFI_TYPE_UINT8:
     272  	case FFI_TYPE_SINT8:
     273  	  /* Everything else is passed as a 4-byte word in a GPR, either
     274  	     the object itself or a pointer to it.  */
     275  	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
     276  	    stack_count += 1;
     277  	  else
     278  	    gpr_count += 1;
     279  	  break;
     280  
     281  	default:
     282  	  FFI_ASSERT (0);
     283  	}
     284      }
     285  
     286    if (fpr_count != 0)
     287      flags |= FLAG_FP_ARGUMENTS;
     288    if (gpr_count > 4)
     289      flags |= FLAG_4_GPR_ARGUMENTS;
     290    if (struct_copy_size != 0)
     291      flags |= FLAG_ARG_NEEDS_COPY;
     292  
     293    /* Space for the FPR registers, if needed.  */
     294    if (fpr_count != 0)
     295      bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
     296  
     297    /* Stack space.  */
     298    bytes += stack_count * sizeof (int);
     299  
     300    /* The stack space allocated needs to be a multiple of 16 bytes.  */
     301    bytes = (bytes + 15) & ~0xF;
     302  
     303    /* Add in the space for the copied structures.  */
     304    bytes += struct_copy_size;
     305  
     306    cif->flags = flags;
     307    cif->bytes = bytes;
     308  
     309    return FFI_OK;
     310  }
     311  
     312  ffi_status FFI_HIDDEN
     313  ffi_prep_cif_sysv (ffi_cif *cif)
     314  {
     315    if ((cif->abi & FFI_SYSV) == 0)
     316      {
     317        /* This call is from old code.  Translate to new ABI values.  */
     318        cif->flags |= FLAG_COMPAT;
     319        switch (cif->abi)
     320  	{
     321  	default:
     322  	  return FFI_BAD_ABI;
     323  
     324  	case FFI_COMPAT_SYSV:
     325  	  cif->abi = FFI_SYSV | FFI_SYSV_STRUCT_RET | FFI_SYSV_LONG_DOUBLE_128;
     326  	  break;
     327  
     328  	case FFI_COMPAT_GCC_SYSV:
     329  	  cif->abi = FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128;
     330  	  break;
     331  
     332  	case FFI_COMPAT_LINUX:
     333  	  cif->abi = (FFI_SYSV | FFI_SYSV_IBM_LONG_DOUBLE
     334  		      | FFI_SYSV_LONG_DOUBLE_128);
     335  	  break;
     336  
     337  	case FFI_COMPAT_LINUX_SOFT_FLOAT:
     338  	  cif->abi = (FFI_SYSV | FFI_SYSV_SOFT_FLOAT | FFI_SYSV_IBM_LONG_DOUBLE
     339  		      | FFI_SYSV_LONG_DOUBLE_128);
     340  	  break;
     341  	}
     342      }
     343    return ffi_prep_cif_sysv_core (cif);
     344  }
     345  
     346  /* ffi_prep_args_SYSV is called by the assembly routine once stack space
     347     has been allocated for the function's arguments.
     348  
     349     The stack layout we want looks like this:
     350  
     351     |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
     352     |--------------------------------------------|
     353     |   Previous backchain pointer	4	|       stack pointer here
     354     |--------------------------------------------|<+ <<<	on entry to
     355     |   Saved r28-r31			4*4	| |	ffi_call_SYSV
     356     |--------------------------------------------| |
     357     |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV
     358     |--------------------------------------------| |
     359     |   FPR registers f1-f8 (optional)	8*8	| |
     360     |--------------------------------------------| |	stack	|
     361     |   Space for copied structures		| |	grows	|
     362     |--------------------------------------------| |	down    V
     363     |   Parameters that didn't fit in registers  | |
     364     |--------------------------------------------| |	lower addresses
     365     |   Space for callee's LR		4	| |
     366     |--------------------------------------------| |	stack pointer here
     367     |   Current backchain pointer	4	|-/	during
     368     |--------------------------------------------|   <<<	ffi_call_SYSV
     369  
     370  */
     371  
     372  void FFI_HIDDEN
     373  ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
     374  {
     375    const unsigned bytes = ecif->cif->bytes;
     376    const unsigned flags = ecif->cif->flags;
     377  
     378    typedef union
     379    {
     380      char *c;
     381      unsigned *u;
     382      long long *ll;
     383      float *f;
     384      double *d;
     385    } valp;
     386  
     387    /* 'stacktop' points at the previous backchain pointer.  */
     388    valp stacktop;
     389  
     390    /* 'gpr_base' points at the space for gpr3, and grows upwards as
     391       we use GPR registers.  */
     392    valp gpr_base;
     393    valp gpr_end;
     394  
     395  #ifndef __NO_FPRS__
     396    /* 'fpr_base' points at the space for fpr1, and grows upwards as
     397       we use FPR registers.  */
     398    valp fpr_base;
     399    valp fpr_end;
     400  #endif
     401  
     402    /* 'copy_space' grows down as we put structures in it.  It should
     403       stay 16-byte aligned.  */
     404    valp copy_space;
     405  
     406    /* 'next_arg' grows up as we put parameters in it.  */
     407    valp next_arg;
     408  
     409    int i;
     410    ffi_type **ptr;
     411  #ifndef __NO_FPRS__
     412    double double_tmp;
     413  #endif
     414    union
     415    {
     416      void **v;
     417      char **c;
     418      signed char **sc;
     419      unsigned char **uc;
     420      signed short **ss;
     421      unsigned short **us;
     422      unsigned int **ui;
     423      long long **ll;
     424      float **f;
     425      double **d;
     426    } p_argv;
     427    size_t struct_copy_size;
     428    unsigned gprvalue;
     429  
     430    stacktop.c = (char *) stack + bytes;
     431    gpr_end.u = stacktop.u - ASM_NEEDS_REGISTERS;
     432    gpr_base.u = gpr_end.u - NUM_GPR_ARG_REGISTERS;
     433  #ifndef __NO_FPRS__
     434    fpr_end.d = gpr_base.d;
     435    fpr_base.d = fpr_end.d - NUM_FPR_ARG_REGISTERS;
     436    copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
     437  #else
     438    copy_space.c = gpr_base.c;
     439  #endif
     440    next_arg.u = stack + 2;
     441  
     442    /* Check that everything starts aligned properly.  */
     443    FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
     444    FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
     445    FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
     446    FFI_ASSERT ((bytes & 0xF) == 0);
     447    FFI_ASSERT (copy_space.c >= next_arg.c);
     448  
     449    /* Deal with return values that are actually pass-by-reference.  */
     450    if (flags & FLAG_RETVAL_REFERENCE)
     451      *gpr_base.u++ = (unsigned) (char *) ecif->rvalue;
     452  
     453    /* Now for the arguments.  */
     454    p_argv.v = ecif->avalue;
     455    for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
     456         i > 0;
     457         i--, ptr++, p_argv.v++)
     458      {
     459        unsigned int typenum = (*ptr)->type;
     460  
     461        typenum = translate_float (ecif->cif->abi, typenum);
     462  
     463        /* Now test the translated value */
     464        switch (typenum)
     465  	{
     466  #ifndef __NO_FPRS__
     467  # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
     468  	case FFI_TYPE_LONGDOUBLE:
     469  	  double_tmp = (*p_argv.d)[0];
     470  
     471  	  if (fpr_base.d >= fpr_end.d - 1)
     472  	    {
     473  	      fpr_base.d = fpr_end.d;
     474  	      if (((next_arg.u - stack) & 1) != 0)
     475  		next_arg.u += 1;
     476  	      *next_arg.d = double_tmp;
     477  	      next_arg.u += 2;
     478  	      double_tmp = (*p_argv.d)[1];
     479  	      *next_arg.d = double_tmp;
     480  	      next_arg.u += 2;
     481  	    }
     482  	  else
     483  	    {
     484  	      *fpr_base.d++ = double_tmp;
     485  	      double_tmp = (*p_argv.d)[1];
     486  	      *fpr_base.d++ = double_tmp;
     487  	    }
     488  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
     489  	  break;
     490  # endif
     491  	case FFI_TYPE_DOUBLE:
     492  	  double_tmp = **p_argv.d;
     493  
     494  	  if (fpr_base.d >= fpr_end.d)
     495  	    {
     496  	      if (((next_arg.u - stack) & 1) != 0)
     497  		next_arg.u += 1;
     498  	      *next_arg.d = double_tmp;
     499  	      next_arg.u += 2;
     500  	    }
     501  	  else
     502  	    *fpr_base.d++ = double_tmp;
     503  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
     504  	  break;
     505  
     506  	case FFI_TYPE_FLOAT:
     507  	  double_tmp = **p_argv.f;
     508  	  if (fpr_base.d >= fpr_end.d)
     509  	    {
     510  	      *next_arg.f = (float) double_tmp;
     511  	      next_arg.u += 1;
     512  	    }
     513  	  else
     514  	    *fpr_base.d++ = double_tmp;
     515  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
     516  	  break;
     517  #endif /* have FPRs */
     518  
     519  	case FFI_TYPE_UINT128:
     520  	  /* The soft float ABI for long doubles works like this, a long double
     521  	     is passed in four consecutive GPRs if available.  A maximum of 2
     522  	     long doubles can be passed in gprs.  If we do not have 4 GPRs
     523  	     left, the long double is passed on the stack, 4-byte aligned.  */
     524  	  if (gpr_base.u >= gpr_end.u - 3)
     525  	    {
     526  	      unsigned int ii;
     527  	      gpr_base.u = gpr_end.u;
     528  	      for (ii = 0; ii < 4; ii++)
     529  		{
     530  		  unsigned int int_tmp = (*p_argv.ui)[ii];
     531  		  *next_arg.u++ = int_tmp;
     532  		}
     533  	    }
     534  	  else
     535  	    {
     536  	      unsigned int ii;
     537  	      for (ii = 0; ii < 4; ii++)
     538  		{
     539  		  unsigned int int_tmp = (*p_argv.ui)[ii];
     540  		  *gpr_base.u++ = int_tmp;
     541  		}
     542  	    }
     543  	  break;
     544  
     545  	case FFI_TYPE_UINT64:
     546  	case FFI_TYPE_SINT64:
     547  	  if (gpr_base.u >= gpr_end.u - 1)
     548  	    {
     549  	      gpr_base.u = gpr_end.u;
     550  	      if (((next_arg.u - stack) & 1) != 0)
     551  		next_arg.u++;
     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 (((gpr_end.u - gpr_base.u) & 1) != 0)
     563  		gpr_base.u++;
     564  	      *gpr_base.ll++ = **p_argv.ll;
     565  	    }
     566  	  break;
     567  
     568  	case FFI_TYPE_STRUCT:
     569  	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
     570  	  copy_space.c -= struct_copy_size;
     571  	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
     572  
     573  	  gprvalue = (unsigned long) copy_space.c;
     574  
     575  	  FFI_ASSERT (copy_space.c > next_arg.c);
     576  	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
     577  	  goto putgpr;
     578  
     579  	case FFI_TYPE_UINT8:
     580  	  gprvalue = **p_argv.uc;
     581  	  goto putgpr;
     582  	case FFI_TYPE_SINT8:
     583  	  gprvalue = **p_argv.sc;
     584  	  goto putgpr;
     585  	case FFI_TYPE_UINT16:
     586  	  gprvalue = **p_argv.us;
     587  	  goto putgpr;
     588  	case FFI_TYPE_SINT16:
     589  	  gprvalue = **p_argv.ss;
     590  	  goto putgpr;
     591  
     592  	case FFI_TYPE_INT:
     593  	case FFI_TYPE_UINT32:
     594  	case FFI_TYPE_SINT32:
     595  	case FFI_TYPE_POINTER:
     596  
     597  	  gprvalue = **p_argv.ui;
     598  
     599  	putgpr:
     600  	  if (gpr_base.u >= gpr_end.u)
     601  	    *next_arg.u++ = gprvalue;
     602  	  else
     603  	    *gpr_base.u++ = gprvalue;
     604  	  break;
     605  	}
     606      }
     607  
     608    /* Check that we didn't overrun the stack...  */
     609    FFI_ASSERT (copy_space.c >= next_arg.c);
     610    FFI_ASSERT (gpr_base.u <= gpr_end.u);
     611  #ifndef __NO_FPRS__
     612    FFI_ASSERT (fpr_base.u <= fpr_end.u);
     613  #endif
     614    FFI_ASSERT (((flags & FLAG_4_GPR_ARGUMENTS) != 0)
     615  	      == (gpr_end.u - gpr_base.u < 4));
     616  }
     617  
     618  #define MIN_CACHE_LINE_SIZE 8
     619  
     620  static void
     621  flush_icache (char *wraddr, char *xaddr, int size)
     622  {
     623    int i;
     624    for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
     625      __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
     626  		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
     627    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
     628  		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
     629  		    : "memory");
     630  }
     631  
     632  ffi_status FFI_HIDDEN
     633  ffi_prep_closure_loc_sysv (ffi_closure *closure,
     634  			   ffi_cif *cif,
     635  			   void (*fun) (ffi_cif *, void *, void **, void *),
     636  			   void *user_data,
     637  			   void *codeloc)
     638  {
     639    unsigned int *tramp;
     640  
     641    if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI)
     642      return FFI_BAD_ABI;
     643  
     644    tramp = (unsigned int *) &closure->tramp[0];
     645    tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
     646    tramp[1] = 0x429f0005;  /*   bcl     20,31,.+4 */
     647    tramp[2] = 0x7d6802a6;  /*   mflr    r11 */
     648    tramp[3] = 0x7c0803a6;  /*   mtlr    r0 */
     649    tramp[4] = 0x800b0018;  /*   lwz     r0,24(r11) */
     650    tramp[5] = 0x816b001c;  /*   lwz     r11,28(r11) */
     651    tramp[6] = 0x7c0903a6;  /*   mtctr   r0 */
     652    tramp[7] = 0x4e800420;  /*   bctr */
     653    *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */
     654    *(void **) &tramp[9] = codeloc;                   /* context */
     655  
     656    /* Flush the icache.  */
     657    flush_icache ((char *)tramp, (char *)codeloc, 8 * 4);
     658  
     659    closure->cif = cif;
     660    closure->fun = fun;
     661    closure->user_data = user_data;
     662  
     663    return FFI_OK;
     664  }
     665  
     666  /* Basically the trampoline invokes ffi_closure_SYSV, and on
     667     entry, r11 holds the address of the closure.
     668     After storing the registers that could possibly contain
     669     parameters to be passed into the stack frame and setting
     670     up space for a return value, ffi_closure_SYSV invokes the
     671     following helper function to do most of the work.  */
     672  
     673  int
     674  ffi_closure_helper_SYSV (ffi_cif *cif,
     675  			 void (*fun) (ffi_cif *, void *, void **, void *),
     676  			 void *user_data,
     677  			 void *rvalue,
     678  			 unsigned long *pgr,
     679  			 ffi_dblfl *pfr,
     680  			 unsigned long *pst)
     681  {
     682    /* rvalue is the pointer to space for return value in closure assembly */
     683    /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
     684    /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
     685    /* pst is the pointer to outgoing parameter stack in original caller */
     686  
     687    void **          avalue;
     688    ffi_type **      arg_types;
     689    long             i, avn;
     690  #ifndef __NO_FPRS__
     691    long             nf = 0;   /* number of floating registers already used */
     692  #endif
     693    long             ng = 0;   /* number of general registers already used */
     694  
     695    unsigned       size     = cif->rtype->size;
     696    unsigned short rtypenum = cif->rtype->type;
     697  
     698    avalue = alloca (cif->nargs * sizeof (void *));
     699  
     700    /* First translate for softfloat/nonlinux */
     701    rtypenum = translate_float (cif->abi, rtypenum);
     702  
     703    /* Copy the caller's structure return value address so that the closure
     704       returns the data directly to the caller.
     705       For FFI_SYSV the result is passed in r3/r4 if the struct size is less
     706       or equal 8 bytes.  */
     707    if (rtypenum == FFI_TYPE_STRUCT
     708        && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8))
     709      {
     710        rvalue = (void *) *pgr;
     711        ng++;
     712        pgr++;
     713      }
     714  
     715    i = 0;
     716    avn = cif->nargs;
     717    arg_types = cif->arg_types;
     718  
     719    /* Grab the addresses of the arguments from the stack frame.  */
     720    while (i < avn) {
     721      unsigned short typenum = arg_types[i]->type;
     722  
     723      /* We may need to handle some values depending on ABI.  */
     724      typenum = translate_float (cif->abi, typenum);
     725  
     726      switch (typenum)
     727        {
     728  #ifndef __NO_FPRS__
     729        case FFI_TYPE_FLOAT:
     730  	/* Unfortunately float values are stored as doubles
     731  	   in the ffi_closure_SYSV code (since we don't check
     732  	   the type in that routine).  */
     733  	if (nf < NUM_FPR_ARG_REGISTERS)
     734  	  {
     735  	    /* FIXME? here we are really changing the values
     736  	       stored in the original calling routines outgoing
     737  	       parameter stack.  This is probably a really
     738  	       naughty thing to do but...  */
     739  	    double temp = pfr->d;
     740  	    pfr->f = (float) temp;
     741  	    avalue[i] = pfr;
     742  	    nf++;
     743  	    pfr++;
     744  	  }
     745  	else
     746  	  {
     747  	    avalue[i] = pst;
     748  	    pst += 1;
     749  	  }
     750  	break;
     751  
     752        case FFI_TYPE_DOUBLE:
     753  	if (nf < NUM_FPR_ARG_REGISTERS)
     754  	  {
     755  	    avalue[i] = pfr;
     756  	    nf++;
     757  	    pfr++;
     758  	  }
     759  	else
     760  	  {
     761  	    if (((long) pst) & 4)
     762  	      pst++;
     763  	    avalue[i] = pst;
     764  	    pst += 2;
     765  	  }
     766  	break;
     767  
     768  # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
     769        case FFI_TYPE_LONGDOUBLE:
     770  	if (nf < NUM_FPR_ARG_REGISTERS - 1)
     771  	  {
     772  	    avalue[i] = pfr;
     773  	    pfr += 2;
     774  	    nf += 2;
     775  	  }
     776  	else
     777  	  {
     778  	    if (((long) pst) & 4)
     779  	      pst++;
     780  	    avalue[i] = pst;
     781  	    pst += 4;
     782  	    nf = 8;
     783  	  }
     784  	break;
     785  # endif
     786  #endif
     787  
     788        case FFI_TYPE_UINT128:
     789  	/* Test if for the whole long double, 4 gprs are available.
     790  	   otherwise the stuff ends up on the stack.  */
     791  	if (ng < NUM_GPR_ARG_REGISTERS - 3)
     792  	  {
     793  	    avalue[i] = pgr;
     794  	    pgr += 4;
     795  	    ng += 4;
     796  	  }
     797  	else
     798  	  {
     799  	    avalue[i] = pst;
     800  	    pst += 4;
     801  	    ng = 8+4;
     802  	  }
     803  	break;
     804  
     805        case FFI_TYPE_SINT8:
     806        case FFI_TYPE_UINT8:
     807  #ifndef __LITTLE_ENDIAN__
     808  	if (ng < NUM_GPR_ARG_REGISTERS)
     809  	  {
     810  	    avalue[i] = (char *) pgr + 3;
     811  	    ng++;
     812  	    pgr++;
     813  	  }
     814  	else
     815  	  {
     816  	    avalue[i] = (char *) pst + 3;
     817  	    pst++;
     818  	  }
     819  	break;
     820  #endif
     821  
     822        case FFI_TYPE_SINT16:
     823        case FFI_TYPE_UINT16:
     824  #ifndef __LITTLE_ENDIAN__
     825  	if (ng < NUM_GPR_ARG_REGISTERS)
     826  	  {
     827  	    avalue[i] = (char *) pgr + 2;
     828  	    ng++;
     829  	    pgr++;
     830  	  }
     831  	else
     832  	  {
     833  	    avalue[i] = (char *) pst + 2;
     834  	    pst++;
     835  	  }
     836  	break;
     837  #endif
     838  
     839        case FFI_TYPE_SINT32:
     840        case FFI_TYPE_UINT32:
     841        case FFI_TYPE_POINTER:
     842  	if (ng < NUM_GPR_ARG_REGISTERS)
     843  	  {
     844  	    avalue[i] = pgr;
     845  	    ng++;
     846  	    pgr++;
     847  	  }
     848  	else
     849  	  {
     850  	    avalue[i] = pst;
     851  	    pst++;
     852  	  }
     853  	break;
     854  
     855        case FFI_TYPE_STRUCT:
     856  	/* Structs are passed by reference. The address will appear in a
     857  	   gpr if it is one of the first 8 arguments.  */
     858  	if (ng < NUM_GPR_ARG_REGISTERS)
     859  	  {
     860  	    avalue[i] = (void *) *pgr;
     861  	    ng++;
     862  	    pgr++;
     863  	  }
     864  	else
     865  	  {
     866  	    avalue[i] = (void *) *pst;
     867  	    pst++;
     868  	  }
     869  	break;
     870  
     871        case FFI_TYPE_SINT64:
     872        case FFI_TYPE_UINT64:
     873  	/* Passing long long ints are complex, they must
     874  	   be passed in suitable register pairs such as
     875  	   (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
     876  	   and if the entire pair aren't available then the outgoing
     877  	   parameter stack is used for both but an alignment of 8
     878  	   must will be kept.  So we must either look in pgr
     879  	   or pst to find the correct address for this type
     880  	   of parameter.  */
     881  	if (ng < NUM_GPR_ARG_REGISTERS - 1)
     882  	  {
     883  	    if (ng & 1)
     884  	      {
     885  		/* skip r4, r6, r8 as starting points */
     886  		ng++;
     887  		pgr++;
     888  	      }
     889  	    avalue[i] = pgr;
     890  	    ng += 2;
     891  	    pgr += 2;
     892  	  }
     893  	else
     894  	  {
     895  	    if (((long) pst) & 4)
     896  	      pst++;
     897  	    avalue[i] = pst;
     898  	    pst += 2;
     899  	    ng = NUM_GPR_ARG_REGISTERS;
     900  	  }
     901  	break;
     902  
     903        default:
     904  	FFI_ASSERT (0);
     905        }
     906  
     907      i++;
     908    }
     909  
     910    (*fun) (cif, rvalue, avalue, user_data);
     911  
     912    /* Tell ffi_closure_SYSV how to perform return type promotions.
     913       Because the FFI_SYSV ABI returns the structures <= 8 bytes in
     914       r3/r4 we have to tell ffi_closure_SYSV how to treat them.  We
     915       combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of
     916       the struct less one.  We never have a struct with size zero.
     917       See the comment in ffitarget.h about ordering.  */
     918    if (rtypenum == FFI_TYPE_STRUCT
     919        && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)
     920      return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size;
     921    return rtypenum;
     922  }
     923  #endif