Home | History | Annotate | Download | only in powerpc
      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 4
     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] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
    658   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
    659   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
    660   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
    661   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
    662   tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
    663   tramp[9] = 0x4e800420;  /*   bctr */
    664   *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
    665   *(void **) &tramp[3] = codeloc;                   /* context */
    666 
    667   /* Flush the icache.  */
    668   flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
    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_closure *closure, void *rvalue,
    686 			 unsigned long *pgr, ffi_dblfl *pfr,
    687 			 unsigned long *pst)
    688 {
    689   /* rvalue is the pointer to space for return value in closure assembly */
    690   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
    691   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
    692   /* pst is the pointer to outgoing parameter stack in original caller */
    693 
    694   void **          avalue;
    695   ffi_type **      arg_types;
    696   long             i, avn;
    697 #ifndef __NO_FPRS__
    698   long             nf = 0;   /* number of floating registers already used */
    699 #endif
    700   long             ng = 0;   /* number of general registers already used */
    701 
    702   ffi_cif *cif = closure->cif;
    703   unsigned       size     = cif->rtype->size;
    704   unsigned short rtypenum = cif->rtype->type;
    705 
    706   avalue = alloca (cif->nargs * sizeof (void *));
    707 
    708   /* First translate for softfloat/nonlinux */
    709   rtypenum = translate_float (cif->abi, rtypenum);
    710 
    711   /* Copy the caller's structure return value address so that the closure
    712      returns the data directly to the caller.
    713      For FFI_SYSV the result is passed in r3/r4 if the struct size is less
    714      or equal 8 bytes.  */
    715   if (rtypenum == FFI_TYPE_STRUCT
    716       && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8))
    717     {
    718       rvalue = (void *) *pgr;
    719       ng++;
    720       pgr++;
    721     }
    722 
    723   i = 0;
    724   avn = cif->nargs;
    725   arg_types = cif->arg_types;
    726 
    727   /* Grab the addresses of the arguments from the stack frame.  */
    728   while (i < avn) {
    729     unsigned short typenum = arg_types[i]->type;
    730 
    731     /* We may need to handle some values depending on ABI.  */
    732     typenum = translate_float (cif->abi, typenum);
    733 
    734     switch (typenum)
    735       {
    736 #ifndef __NO_FPRS__
    737       case FFI_TYPE_FLOAT:
    738 	/* Unfortunately float values are stored as doubles
    739 	   in the ffi_closure_SYSV code (since we don't check
    740 	   the type in that routine).  */
    741 	if (nf < NUM_FPR_ARG_REGISTERS)
    742 	  {
    743 	    /* FIXME? here we are really changing the values
    744 	       stored in the original calling routines outgoing
    745 	       parameter stack.  This is probably a really
    746 	       naughty thing to do but...  */
    747 	    double temp = pfr->d;
    748 	    pfr->f = (float) temp;
    749 	    avalue[i] = pfr;
    750 	    nf++;
    751 	    pfr++;
    752 	  }
    753 	else
    754 	  {
    755 	    avalue[i] = pst;
    756 	    pst += 1;
    757 	  }
    758 	break;
    759 
    760       case FFI_TYPE_DOUBLE:
    761 	if (nf < NUM_FPR_ARG_REGISTERS)
    762 	  {
    763 	    avalue[i] = pfr;
    764 	    nf++;
    765 	    pfr++;
    766 	  }
    767 	else
    768 	  {
    769 	    if (((long) pst) & 4)
    770 	      pst++;
    771 	    avalue[i] = pst;
    772 	    pst += 2;
    773 	  }
    774 	break;
    775 
    776 # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
    777       case FFI_TYPE_LONGDOUBLE:
    778 	if (nf < NUM_FPR_ARG_REGISTERS - 1)
    779 	  {
    780 	    avalue[i] = pfr;
    781 	    pfr += 2;
    782 	    nf += 2;
    783 	  }
    784 	else
    785 	  {
    786 	    if (((long) pst) & 4)
    787 	      pst++;
    788 	    avalue[i] = pst;
    789 	    pst += 4;
    790 	    nf = 8;
    791 	  }
    792 	break;
    793 # endif
    794 #endif
    795 
    796       case FFI_TYPE_UINT128:
    797 	/* Test if for the whole long double, 4 gprs are available.
    798 	   otherwise the stuff ends up on the stack.  */
    799 	if (ng < NUM_GPR_ARG_REGISTERS - 3)
    800 	  {
    801 	    avalue[i] = pgr;
    802 	    pgr += 4;
    803 	    ng += 4;
    804 	  }
    805 	else
    806 	  {
    807 	    avalue[i] = pst;
    808 	    pst += 4;
    809 	    ng = 8+4;
    810 	  }
    811 	break;
    812 
    813       case FFI_TYPE_SINT8:
    814       case FFI_TYPE_UINT8:
    815 #ifndef __LITTLE_ENDIAN__
    816 	if (ng < NUM_GPR_ARG_REGISTERS)
    817 	  {
    818 	    avalue[i] = (char *) pgr + 3;
    819 	    ng++;
    820 	    pgr++;
    821 	  }
    822 	else
    823 	  {
    824 	    avalue[i] = (char *) pst + 3;
    825 	    pst++;
    826 	  }
    827 	break;
    828 #endif
    829 
    830       case FFI_TYPE_SINT16:
    831       case FFI_TYPE_UINT16:
    832 #ifndef __LITTLE_ENDIAN__
    833 	if (ng < NUM_GPR_ARG_REGISTERS)
    834 	  {
    835 	    avalue[i] = (char *) pgr + 2;
    836 	    ng++;
    837 	    pgr++;
    838 	  }
    839 	else
    840 	  {
    841 	    avalue[i] = (char *) pst + 2;
    842 	    pst++;
    843 	  }
    844 	break;
    845 #endif
    846 
    847       case FFI_TYPE_SINT32:
    848       case FFI_TYPE_UINT32:
    849       case FFI_TYPE_POINTER:
    850 	if (ng < NUM_GPR_ARG_REGISTERS)
    851 	  {
    852 	    avalue[i] = pgr;
    853 	    ng++;
    854 	    pgr++;
    855 	  }
    856 	else
    857 	  {
    858 	    avalue[i] = pst;
    859 	    pst++;
    860 	  }
    861 	break;
    862 
    863       case FFI_TYPE_STRUCT:
    864 	/* Structs are passed by reference. The address will appear in a
    865 	   gpr if it is one of the first 8 arguments.  */
    866 	if (ng < NUM_GPR_ARG_REGISTERS)
    867 	  {
    868 	    avalue[i] = (void *) *pgr;
    869 	    ng++;
    870 	    pgr++;
    871 	  }
    872 	else
    873 	  {
    874 	    avalue[i] = (void *) *pst;
    875 	    pst++;
    876 	  }
    877 	break;
    878 
    879       case FFI_TYPE_SINT64:
    880       case FFI_TYPE_UINT64:
    881 	/* Passing long long ints are complex, they must
    882 	   be passed in suitable register pairs such as
    883 	   (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
    884 	   and if the entire pair aren't available then the outgoing
    885 	   parameter stack is used for both but an alignment of 8
    886 	   must will be kept.  So we must either look in pgr
    887 	   or pst to find the correct address for this type
    888 	   of parameter.  */
    889 	if (ng < NUM_GPR_ARG_REGISTERS - 1)
    890 	  {
    891 	    if (ng & 1)
    892 	      {
    893 		/* skip r4, r6, r8 as starting points */
    894 		ng++;
    895 		pgr++;
    896 	      }
    897 	    avalue[i] = pgr;
    898 	    ng += 2;
    899 	    pgr += 2;
    900 	  }
    901 	else
    902 	  {
    903 	    if (((long) pst) & 4)
    904 	      pst++;
    905 	    avalue[i] = pst;
    906 	    pst += 2;
    907 	    ng = NUM_GPR_ARG_REGISTERS;
    908 	  }
    909 	break;
    910 
    911       default:
    912 	FFI_ASSERT (0);
    913       }
    914 
    915     i++;
    916   }
    917 
    918   (closure->fun) (cif, rvalue, avalue, closure->user_data);
    919 
    920   /* Tell ffi_closure_SYSV how to perform return type promotions.
    921      Because the FFI_SYSV ABI returns the structures <= 8 bytes in
    922      r3/r4 we have to tell ffi_closure_SYSV how to treat them.  We
    923      combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of
    924      the struct less one.  We never have a struct with size zero.
    925      See the comment in ffitarget.h about ordering.  */
    926   if (rtypenum == FFI_TYPE_STRUCT
    927       && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)
    928     return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size;
    929   return rtypenum;
    930 }
    931 #endif
    932