/* -----------------------------------------------------------------------
   ffi.c - Copyright (c) 1998 Geoffrey Keating
   Copyright (C) 2007 Free Software Foundation, Inc
   Copyright (C) 2008 Red Hat, Inc

   PowerPC Foreign Function Interface

   Permission is hereby granted, free of charge, to any person obtaining
   a copy of this software and associated documentation files (the
   ``Software''), to deal in the Software without restriction, including
   without limitation the rights to use, copy, modify, merge, publish,
   distribute, sublicense, and/or sell copies of the Software, and to
   permit persons to whom the Software is furnished to do so, subject to
   the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   OTHER DEALINGS IN THE SOFTWARE.
   ----------------------------------------------------------------------- */

#include <ffi.h>
#include <ffi_common.h>

#include <stdlib.h>
#include <stdio.h>


extern void ffi_closure_SYSV (void);
extern void FFI_HIDDEN ffi_closure_LINUX64 (void);

enum {
  /* The assembly depends on these exact flags.  */
  FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
  FLAG_RETURNS_FP       = 1 << (31-29),
  FLAG_RETURNS_64BITS   = 1 << (31-28),

  FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */

  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
};

/* About the SYSV ABI.  */
unsigned int NUM_GPR_ARG_REGISTERS = 8;
#ifndef __NO_FPRS__
unsigned int NUM_FPR_ARG_REGISTERS = 8;
#else
unsigned int NUM_FPR_ARG_REGISTERS = 0;
#endif

enum { ASM_NEEDS_REGISTERS = 4 };

/* ffi_prep_args_SYSV is called by the assembly routine once stack space
   has been allocated for the function's arguments.

   The stack layout we want looks like this:

   |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
   |--------------------------------------------|
   |   Previous backchain pointer	4	|       stack pointer here
   |--------------------------------------------|<+ <<<	on entry to
   |   Saved r28-r31			4*4	| |	ffi_call_SYSV
   |--------------------------------------------| |
   |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV
   |--------------------------------------------| |
   |   FPR registers f1-f8 (optional)	8*8	| |
   |--------------------------------------------| |	stack	|
   |   Space for copied structures		| |	grows	|
   |--------------------------------------------| |	down    V
   |   Parameters that didn't fit in registers  | |
   |--------------------------------------------| |	lower addresses
   |   Space for callee's LR		4	| |
   |--------------------------------------------| |	stack pointer here
   |   Current backchain pointer	4	|-/	during
   |--------------------------------------------|   <<<	ffi_call_SYSV

*/

void
ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
{
  const unsigned bytes = ecif->cif->bytes;
  const unsigned flags = ecif->cif->flags;

  typedef union {
    char *c;
    unsigned *u;
    long long *ll;
    float *f;
    double *d;
  } valp;

  /* 'stacktop' points at the previous backchain pointer.  */
  valp stacktop;

  /* 'gpr_base' points at the space for gpr3, and grows upwards as
     we use GPR registers.  */
  valp gpr_base;
  int intarg_count;

  /* 'fpr_base' points at the space for fpr1, and grows upwards as
     we use FPR registers.  */
  valp fpr_base;
  int fparg_count;

  /* 'copy_space' grows down as we put structures in it.  It should
     stay 16-byte aligned.  */
  valp copy_space;

  /* 'next_arg' grows up as we put parameters in it.  */
  valp next_arg;

  int i, ii MAYBE_UNUSED;
  ffi_type **ptr;
  double double_tmp;
  union {
    void **v;
    char **c;
    signed char **sc;
    unsigned char **uc;
    signed short **ss;
    unsigned short **us;
    unsigned int **ui;
    long long **ll;
    float **f;
    double **d;
  } p_argv;
  size_t struct_copy_size;
  unsigned gprvalue;

  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
    NUM_FPR_ARG_REGISTERS = 0;

  stacktop.c = (char *) stack + bytes;
  gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
  intarg_count = 0;
  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
  fparg_count = 0;
  copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
  next_arg.u = stack + 2;

  /* Check that everything starts aligned properly.  */
  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
  FFI_ASSERT ((bytes & 0xF) == 0);
  FFI_ASSERT (copy_space.c >= next_arg.c);

  /* Deal with return values that are actually pass-by-reference.  */
  if (flags & FLAG_RETVAL_REFERENCE)
    {
      *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
      intarg_count++;
    }

  /* Now for the arguments.  */
  p_argv.v = ecif->avalue;
  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
       i > 0;
       i--, ptr++, p_argv.v++)
    {
      switch ((*ptr)->type)
	{
	case FFI_TYPE_FLOAT:
	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
	    goto soft_float_prep;
	  double_tmp = **p_argv.f;
	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
	    {
	      *next_arg.f = (float) double_tmp;
	      next_arg.u += 1;
	    }
	  else
	    *fpr_base.d++ = double_tmp;
	  fparg_count++;
	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
	  break;

	case FFI_TYPE_DOUBLE:
	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
	    goto soft_double_prep;
	  double_tmp = **p_argv.d;

	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
	    {
	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
		  && intarg_count % 2 != 0)
		{
		  intarg_count++;
		  next_arg.u++;
		}
	      *next_arg.d = double_tmp;
	      next_arg.u += 2;
	    }
	  else
	    *fpr_base.d++ = double_tmp;
	  fparg_count++;
	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
	  break;

#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	case FFI_TYPE_LONGDOUBLE:
	  if ((ecif->cif->abi != FFI_LINUX)
		&& (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
	    goto do_struct;
	  /* The soft float ABI for long doubles works like this,
	     a long double is passed in four consecutive gprs if available.
	     A maximum of 2 long doubles can be passed in gprs.
	     If we do not have 4 gprs left, the long double is passed on the
	     stack, 4-byte aligned.  */
	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
	    {
	      unsigned int int_tmp = (*p_argv.ui)[0];
	      if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
		{
		  if (intarg_count < NUM_GPR_ARG_REGISTERS)
		    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
		  *next_arg.u = int_tmp;
		  next_arg.u++;
		  for (ii = 1; ii < 4; ii++)
		    {
		      int_tmp = (*p_argv.ui)[ii];
		      *next_arg.u = int_tmp;
		      next_arg.u++;
		    }
		}
	      else
		{
		  *gpr_base.u++ = int_tmp;
		  for (ii = 1; ii < 4; ii++)
		    {
		      int_tmp = (*p_argv.ui)[ii];
		      *gpr_base.u++ = int_tmp;
		    }
		}
	      intarg_count +=4;
	    }
	  else
	    {
	      double_tmp = (*p_argv.d)[0];

	      if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
		{
		  if (intarg_count >= NUM_GPR_ARG_REGISTERS
		      && intarg_count % 2 != 0)
		    {
		      intarg_count++;
		      next_arg.u++;
		    }
		  *next_arg.d = double_tmp;
		  next_arg.u += 2;
		  double_tmp = (*p_argv.d)[1];
		  *next_arg.d = double_tmp;
		  next_arg.u += 2;
		}
	      else
		{
		  *fpr_base.d++ = double_tmp;
		  double_tmp = (*p_argv.d)[1];
		  *fpr_base.d++ = double_tmp;
		}

	      fparg_count += 2;
	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
	    }
	  break;
#endif

	case FFI_TYPE_UINT64:
	case FFI_TYPE_SINT64:
	soft_double_prep:
	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
	    intarg_count++;
	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
	    {
	      if (intarg_count % 2 != 0)
		{
		  intarg_count++;
		  next_arg.u++;
		}
	      *next_arg.ll = **p_argv.ll;
	      next_arg.u += 2;
	    }
	  else
	    {
	      /* whoops: abi states only certain register pairs
	       * can be used for passing long long int
	       * specifically (r3,r4), (r5,r6), (r7,r8),
	       * (r9,r10) and if next arg is long long but
	       * not correct starting register of pair then skip
	       * until the proper starting register
	       */
	      if (intarg_count % 2 != 0)
		{
		  intarg_count ++;
		  gpr_base.u++;
		}
	      *gpr_base.ll++ = **p_argv.ll;
	    }
	  intarg_count += 2;
	  break;

	case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	do_struct:
#endif
	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
	  copy_space.c -= struct_copy_size;
	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);

	  gprvalue = (unsigned long) copy_space.c;

	  FFI_ASSERT (copy_space.c > next_arg.c);
	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
	  goto putgpr;

	case FFI_TYPE_UINT8:
	  gprvalue = **p_argv.uc;
	  goto putgpr;
	case FFI_TYPE_SINT8:
	  gprvalue = **p_argv.sc;
	  goto putgpr;
	case FFI_TYPE_UINT16:
	  gprvalue = **p_argv.us;
	  goto putgpr;
	case FFI_TYPE_SINT16:
	  gprvalue = **p_argv.ss;
	  goto putgpr;

	case FFI_TYPE_INT:
	case FFI_TYPE_UINT32:
	case FFI_TYPE_SINT32:
	case FFI_TYPE_POINTER:
	soft_float_prep:

	  gprvalue = **p_argv.ui;

	putgpr:
	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
	    *next_arg.u++ = gprvalue;
	  else
	    *gpr_base.u++ = gprvalue;
	  intarg_count++;
	  break;
	}
    }

  /* Check that we didn't overrun the stack...  */
  FFI_ASSERT (copy_space.c >= next_arg.c);
  FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
  FFI_ASSERT (fpr_base.u
	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
}

/* About the LINUX64 ABI.  */
enum {
  NUM_GPR_ARG_REGISTERS64 = 8,
  NUM_FPR_ARG_REGISTERS64 = 13
};
enum { ASM_NEEDS_REGISTERS64 = 4 };

/* ffi_prep_args64 is called by the assembly routine once stack space
   has been allocated for the function's arguments.

   The stack layout we want looks like this:

   |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses
   |--------------------------------------------|
   |   CR save area			8bytes	|
   |--------------------------------------------|
   |   Previous backchain pointer	8	|	stack pointer here
   |--------------------------------------------|<+ <<<	on entry to
   |   Saved r28-r31			4*8	| |	ffi_call_LINUX64
   |--------------------------------------------| |
   |   GPR registers r3-r10		8*8	| |
   |--------------------------------------------| |
   |   FPR registers f1-f13 (optional)	13*8	| |
   |--------------------------------------------| |
   |   Parameter save area		        | |
   |--------------------------------------------| |
   |   TOC save area			8	| |
   |--------------------------------------------| |	stack	|
   |   Linker doubleword		8	| |	grows	|
   |--------------------------------------------| |	down	V
   |   Compiler doubleword		8	| |
   |--------------------------------------------| |	lower addresses
   |   Space for callee's LR		8	| |
   |--------------------------------------------| |
   |   CR save area			8	| |
   |--------------------------------------------| |	stack pointer here
   |   Current backchain pointer	8	|-/	during
   |--------------------------------------------|   <<<	ffi_call_LINUX64

*/

void FFI_HIDDEN
ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
{
  const unsigned long bytes = ecif->cif->bytes;
  const unsigned long flags = ecif->cif->flags;

  typedef union {
    char *c;
    unsigned long *ul;
    float *f;
    double *d;
  } valp;

  /* 'stacktop' points at the previous backchain pointer.  */
  valp stacktop;

  /* 'next_arg' points at the space for gpr3, and grows upwards as
     we use GPR registers, then continues at rest.  */
  valp gpr_base;
  valp gpr_end;
  valp rest;
  valp next_arg;

  /* 'fpr_base' points at the space for fpr3, and grows upwards as
     we use FPR registers.  */
  valp fpr_base;
  int fparg_count;

  int i, words;
  ffi_type **ptr;
  double double_tmp;
  union {
    void **v;
    char **c;
    signed char **sc;
    unsigned char **uc;
    signed short **ss;
    unsigned short **us;
    signed int **si;
    unsigned int **ui;
    unsigned long **ul;
    float **f;
    double **d;
  } p_argv;
  unsigned long gprvalue;

  stacktop.c = (char *) stack + bytes;
  gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
  gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
  rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
  fparg_count = 0;
  next_arg.ul = gpr_base.ul;

  /* Check that everything starts aligned properly.  */
  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
  FFI_ASSERT ((bytes & 0xF) == 0);

  /* Deal with return values that are actually pass-by-reference.  */
  if (flags & FLAG_RETVAL_REFERENCE)
    *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;

  /* Now for the arguments.  */
  p_argv.v = ecif->avalue;
  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
       i > 0;
       i--, ptr++, p_argv.v++)
    {
      switch ((*ptr)->type)
	{
	case FFI_TYPE_FLOAT:
	  double_tmp = **p_argv.f;
	  *next_arg.f = (float) double_tmp;
	  if (++next_arg.ul == gpr_end.ul)
	    next_arg.ul = rest.ul;
	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
	    *fpr_base.d++ = double_tmp;
	  fparg_count++;
	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
	  break;

	case FFI_TYPE_DOUBLE:
	  double_tmp = **p_argv.d;
	  *next_arg.d = double_tmp;
	  if (++next_arg.ul == gpr_end.ul)
	    next_arg.ul = rest.ul;
	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
	    *fpr_base.d++ = double_tmp;
	  fparg_count++;
	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
	  break;

#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	case FFI_TYPE_LONGDOUBLE:
	  double_tmp = (*p_argv.d)[0];
	  *next_arg.d = double_tmp;
	  if (++next_arg.ul == gpr_end.ul)
	    next_arg.ul = rest.ul;
	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
	    *fpr_base.d++ = double_tmp;
	  fparg_count++;
	  double_tmp = (*p_argv.d)[1];
	  *next_arg.d = double_tmp;
	  if (++next_arg.ul == gpr_end.ul)
	    next_arg.ul = rest.ul;
	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
	    *fpr_base.d++ = double_tmp;
	  fparg_count++;
	  FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
	  break;
#endif

	case FFI_TYPE_STRUCT:
	  words = ((*ptr)->size + 7) / 8;
	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
	    {
	      size_t first = gpr_end.c - next_arg.c;
	      memcpy (next_arg.c, *p_argv.c, first);
	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
	      next_arg.c = rest.c + words * 8 - first;
	    }
	  else
	    {
	      char *where = next_arg.c;

	      /* Structures with size less than eight bytes are passed
		 left-padded.  */
	      if ((*ptr)->size < 8)
		where += 8 - (*ptr)->size;

	      memcpy (where, *p_argv.c, (*ptr)->size);
	      next_arg.ul += words;
	      if (next_arg.ul == gpr_end.ul)
		next_arg.ul = rest.ul;
	    }
	  break;

	case FFI_TYPE_UINT8:
	  gprvalue = **p_argv.uc;
	  goto putgpr;
	case FFI_TYPE_SINT8:
	  gprvalue = **p_argv.sc;
	  goto putgpr;
	case FFI_TYPE_UINT16:
	  gprvalue = **p_argv.us;
	  goto putgpr;
	case FFI_TYPE_SINT16:
	  gprvalue = **p_argv.ss;
	  goto putgpr;
	case FFI_TYPE_UINT32:
	  gprvalue = **p_argv.ui;
	  goto putgpr;
	case FFI_TYPE_INT:
	case FFI_TYPE_SINT32:
	  gprvalue = **p_argv.si;
	  goto putgpr;

	case FFI_TYPE_UINT64:
	case FFI_TYPE_SINT64:
	case FFI_TYPE_POINTER:
	  gprvalue = **p_argv.ul;
	putgpr:
	  *next_arg.ul++ = gprvalue;
	  if (next_arg.ul == gpr_end.ul)
	    next_arg.ul = rest.ul;
	  break;
	}
    }

  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
	      || (next_arg.ul >= gpr_base.ul
		  && next_arg.ul <= gpr_base.ul + 4));
}



/* Perform machine dependent cif processing */
ffi_status
ffi_prep_cif_machdep (ffi_cif *cif)
{
  /* All this is for the SYSV and LINUX64 ABI.  */
  int i;
  ffi_type **ptr;
  unsigned bytes;
  int fparg_count = 0, intarg_count = 0;
  unsigned flags = 0;
  unsigned struct_copy_size = 0;
  unsigned type = cif->rtype->type;
  unsigned size = cif->rtype->size;

  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
    NUM_FPR_ARG_REGISTERS = 0;

  if (cif->abi != FFI_LINUX64)
    {
      /* All the machine-independent calculation of cif->bytes will be wrong.
	 Redo the calculation for SYSV.  */

      /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);

      /* Space for the GPR registers.  */
      bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
    }
  else
    {
      /* 64-bit ABI.  */

      /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
	 regs.  */
      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);

      /* Space for the mandatory parm save area and general registers.  */
      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
    }

  /* Return value handling.  The rules for SYSV are as follows:
     - 32-bit (or less) integer values are returned in gpr3;
     - Structures of size <= 4 bytes also returned in gpr3;
     - 64-bit integer values and structures between 5 and 8 bytes are returned
     in gpr3 and gpr4;
     - Single/double FP values are returned in fpr1;
     - Larger structures are allocated space and a pointer is passed as
     the first argument.
     - long doubles (if not equivalent to double) are returned in
     fpr1,fpr2 for Linux and as for large structs for SysV.
     For LINUX64:
     - integer values in gpr3;
     - Structures/Unions by reference;
     - Single/double FP values in fpr1, long double in fpr1,fpr2.
     - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
     - soft-float long doubles are returned in gpr3-gpr6.  */
  switch (type)
    {
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
    case FFI_TYPE_LONGDOUBLE:
      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
	&& cif->abi != FFI_LINUX_SOFT_FLOAT)
	goto byref;
      flags |= FLAG_RETURNS_128BITS;
      /* Fall through.  */
#endif
    case FFI_TYPE_DOUBLE:
      flags |= FLAG_RETURNS_64BITS;
      /* Fall through.  */
    case FFI_TYPE_FLOAT:
      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
	flags |= FLAG_RETURNS_FP;
      break;

    case FFI_TYPE_UINT64:
    case FFI_TYPE_SINT64:
      flags |= FLAG_RETURNS_64BITS;
      break;

    case FFI_TYPE_STRUCT:
      if (cif->abi == FFI_SYSV)
	{
	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
	     in memory.  */

	  /* Treat structs with size <= 8 bytes.  */
	  if (size <= 8)
	    {
	      flags |= FLAG_RETURNS_SMST;
	      /* These structs are returned in r3. We pack the type and the
		 precalculated shift value (needed in the sysv.S) into flags.
		 The same applies for the structs returned in r3/r4.  */
	      if (size <= 4)
		{
		  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1);
		  flags |= 8 * (4 - size) << 4;
		  break;
		}
	      /* These structs are returned in r3 and r4. See above.   */
	      if  (size <= 8)
		{
		  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2);
		  flags |= 8 * (8 - size) << 4;
		  break;
		}
	    }
	}
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
    byref:
#endif
      intarg_count++;
      flags |= FLAG_RETVAL_REFERENCE;
      /* Fall through.  */
    case FFI_TYPE_VOID:
      flags |= FLAG_RETURNS_NOTHING;
      break;

    default:
      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
      break;
    }

  if (cif->abi != FFI_LINUX64)
    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
       goes on the stack.  Structures and long doubles (if not equivalent
       to double) are passed as a pointer to a copy of the structure.
       Stuff on the stack needs to keep proper alignment.  */
    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
      {
	switch ((*ptr)->type)
	  {
	  case FFI_TYPE_FLOAT:
	    /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
	      goto soft_float_cif;
	    fparg_count++;
	    /* floating singles are not 8-aligned on stack */
	    break;

#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	  case FFI_TYPE_LONGDOUBLE:
	    if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
	      goto do_struct;
	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
	      {
		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
		  || intarg_count < NUM_GPR_ARG_REGISTERS)
		  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
		     a set of four consecutive gprs. If we have not enough,
		     we have to adjust the intarg_count value.  */
		  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
		intarg_count += 4;
		break;
	      }
	    else
	      fparg_count++;
	    /* Fall thru */
#endif
	  case FFI_TYPE_DOUBLE:
	    /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
	      goto soft_double_cif;
	    fparg_count++;
	    /* If this FP arg is going on the stack, it must be
	       8-byte-aligned.  */
	    if (fparg_count > NUM_FPR_ARG_REGISTERS
		&& intarg_count >= NUM_GPR_ARG_REGISTERS
		&& intarg_count % 2 != 0)
	      intarg_count++;
	    break;

	  case FFI_TYPE_UINT64:
	  case FFI_TYPE_SINT64:
	  soft_double_cif:
	    /* 'long long' arguments are passed as two words, but
	       either both words must fit in registers or both go
	       on the stack.  If they go on the stack, they must
	       be 8-byte-aligned.

	       Also, only certain register pairs can be used for
	       passing long long int -- specifically (r3,r4), (r5,r6),
	       (r7,r8), (r9,r10).
	    */
	    if (intarg_count == NUM_GPR_ARG_REGISTERS-1
		|| intarg_count % 2 != 0)
	      intarg_count++;
	    intarg_count += 2;
	    break;

	  case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	  do_struct:
#endif
	    /* We must allocate space for a copy of these to enforce
	       pass-by-value.  Pad the space up to a multiple of 16
	       bytes (the maximum alignment required for anything under
	       the SYSV ABI).  */
	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
	    /* Fall through (allocate space for the pointer).  */

	  default:
	  soft_float_cif:
	    /* Everything else is passed as a 4-byte word in a GPR, either
	       the object itself or a pointer to it.  */
	    intarg_count++;
	    break;
	  }
      }
  else
    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
      {
	switch ((*ptr)->type)
	  {
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	  case FFI_TYPE_LONGDOUBLE:
	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
	      intarg_count += 4;
	    else
	      {
		fparg_count += 2;
		intarg_count += 2;
	      }
	    break;
#endif
	  case FFI_TYPE_FLOAT:
	  case FFI_TYPE_DOUBLE:
	    fparg_count++;
	    intarg_count++;
	    break;

	  case FFI_TYPE_STRUCT:
	    intarg_count += ((*ptr)->size + 7) / 8;
	    break;

	  default:
	    /* Everything else is passed as a 8-byte word in a GPR, either
	       the object itself or a pointer to it.  */
	    intarg_count++;
	    break;
	  }
      }

  if (fparg_count != 0)
    flags |= FLAG_FP_ARGUMENTS;
  if (intarg_count > 4)
    flags |= FLAG_4_GPR_ARGUMENTS;
  if (struct_copy_size != 0)
    flags |= FLAG_ARG_NEEDS_COPY;

  if (cif->abi != FFI_LINUX64)
    {
      /* Space for the FPR registers, if needed.  */
      if (fparg_count != 0)
	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);

      /* Stack space.  */
      if (intarg_count > NUM_GPR_ARG_REGISTERS)
	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
      if (fparg_count > NUM_FPR_ARG_REGISTERS)
	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
    }
  else
    {
      /* Space for the FPR registers, if needed.  */
      if (fparg_count != 0)
	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);

      /* Stack space.  */
      if (intarg_count > NUM_GPR_ARG_REGISTERS64)
	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
    }

  /* The stack space allocated needs to be a multiple of 16 bytes.  */
  bytes = (bytes + 15) & ~0xF;

  /* Add in the space for the copied structures.  */
  bytes += struct_copy_size;

  cif->flags = flags;
  cif->bytes = bytes;

  return FFI_OK;
}

extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
			  void (*fn)(void));
extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
					unsigned long, unsigned long *,
					void (*fn)(void));

void
ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
  extended_cif ecif;

  ecif.cif = cif;
  ecif.avalue = avalue;

  /* If the return value is a struct and we don't have a return	*/
  /* value address then we need to make one		        */

  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
    {
      ecif.rvalue = alloca(cif->rtype->size);
    }
  else
    ecif.rvalue = rvalue;


  switch (cif->abi)
    {
#ifndef POWERPC64
    case FFI_SYSV:
    case FFI_GCC_SYSV:
    case FFI_LINUX:
    case FFI_LINUX_SOFT_FLOAT:
      ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
      break;
#else
    case FFI_LINUX64:
      ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
      break;
#endif
    default:
      FFI_ASSERT (0);
      break;
    }
}


#ifndef POWERPC64
#define MIN_CACHE_LINE_SIZE 8

static void
flush_icache (char *wraddr, char *xaddr, int size)
{
  int i;
  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
		    : "memory");
}
#endif

ffi_status
ffi_prep_closure_loc (ffi_closure *closure,
		      ffi_cif *cif,
		      void (*fun) (ffi_cif *, void *, void **, void *),
		      void *user_data,
		      void *codeloc)
{
#ifdef POWERPC64
  void **tramp = (void **) &closure->tramp[0];

  FFI_ASSERT (cif->abi == FFI_LINUX64);
  /* Copy function address and TOC from ffi_closure_LINUX64.  */
  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
  tramp[2] = codeloc;
#else
  unsigned int *tramp;

  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);

  tramp = (unsigned int *) &closure->tramp[0];
  tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
  tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
  tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
  tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
  tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
  tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
  tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
  tramp[9] = 0x4e800420;  /*   bctr */
  *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
  *(void **) &tramp[3] = codeloc;                   /* context */

  /* Flush the icache.  */
  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
#endif

  closure->cif = cif;
  closure->fun = fun;
  closure->user_data = user_data;

  return FFI_OK;
}

typedef union
{
  float f;
  double d;
} ffi_dblfl;

int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
			     ffi_dblfl *, unsigned long *);

/* Basically the trampoline invokes ffi_closure_SYSV, and on
 * entry, r11 holds the address of the closure.
 * After storing the registers that could possibly contain
 * parameters to be passed into the stack frame and setting
 * up space for a return value, ffi_closure_SYSV invokes the
 * following helper function to do most of the work
 */

int
ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
			 unsigned long *pgr, ffi_dblfl *pfr,
			 unsigned long *pst)
{
  /* rvalue is the pointer to space for return value in closure assembly */
  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
  /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
  /* pst is the pointer to outgoing parameter stack in original caller */

  void **          avalue;
  ffi_type **      arg_types;
  long             i, avn;
  long             nf;   /* number of floating registers already used */
  long             ng;   /* number of general registers already used */
  ffi_cif *        cif;
  double           temp;
  unsigned         size;

  cif = closure->cif;
  avalue = alloca (cif->nargs * sizeof (void *));
  size = cif->rtype->size;

  nf = 0;
  ng = 0;

  /* Copy the caller's structure return value address so that the closure
     returns the data directly to the caller.
     For FFI_SYSV the result is passed in r3/r4 if the struct size is less
     or equal 8 bytes.  */

  if ((cif->rtype->type == FFI_TYPE_STRUCT
       && !((cif->abi == FFI_SYSV) && (size <= 8)))
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
	  && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
#endif
      )
    {
      rvalue = (void *) *pgr;
      ng++;
      pgr++;
    }

  i = 0;
  avn = cif->nargs;
  arg_types = cif->arg_types;

  /* Grab the addresses of the arguments from the stack frame.  */
  while (i < avn)
    {
      switch (arg_types[i]->type)
	{
	case FFI_TYPE_SINT8:
	case FFI_TYPE_UINT8:
	  /* there are 8 gpr registers used to pass values */
	  if (ng < 8)
	    {
	      avalue[i] = (char *) pgr + 3;
	      ng++;
	      pgr++;
	    }
	  else
	    {
	      avalue[i] = (char *) pst + 3;
	      pst++;
	    }
	  break;

	case FFI_TYPE_SINT16:
	case FFI_TYPE_UINT16:
	  /* there are 8 gpr registers used to pass values */
	  if (ng < 8)
	    {
	      avalue[i] = (char *) pgr + 2;
	      ng++;
	      pgr++;
	    }
	  else
	    {
	      avalue[i] = (char *) pst + 2;
	      pst++;
	    }
	  break;

	case FFI_TYPE_SINT32:
	case FFI_TYPE_UINT32:
	case FFI_TYPE_POINTER:
	soft_float_closure:
	  /* there are 8 gpr registers used to pass values */
	  if (ng < 8)
	    {
	      avalue[i] = pgr;
	      ng++;
	      pgr++;
	    }
	  else
	    {
	      avalue[i] = pst;
	      pst++;
	    }
	  break;

	case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	do_struct:
#endif
	  /* Structs are passed by reference. The address will appear in a
	     gpr if it is one of the first 8 arguments.  */
	  if (ng < 8)
	    {
	      avalue[i] = (void *) *pgr;
	      ng++;
	      pgr++;
	    }
	  else
	    {
	      avalue[i] = (void *) *pst;
	      pst++;
	    }
	  break;

	case FFI_TYPE_SINT64:
	case FFI_TYPE_UINT64:
	soft_double_closure:
	  /* passing long long ints are complex, they must
	   * be passed in suitable register pairs such as
	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
	   * and if the entire pair aren't available then the outgoing
	   * parameter stack is used for both but an alignment of 8
	   * must will be kept.  So we must either look in pgr
	   * or pst to find the correct address for this type
	   * of parameter.
	   */
	  if (ng < 7)
	    {
	      if (ng & 0x01)
		{
		  /* skip r4, r6, r8 as starting points */
		  ng++;
		  pgr++;
		}
	      avalue[i] = pgr;
	      ng += 2;
	      pgr += 2;
	    }
	  else
	    {
	      if (((long) pst) & 4)
		pst++;
	      avalue[i] = pst;
	      pst += 2;
	    }
	  break;

	case FFI_TYPE_FLOAT:
	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
	    goto soft_float_closure;
	  /* unfortunately float values are stored as doubles
	   * in the ffi_closure_SYSV code (since we don't check
	   * the type in that routine).
	   */

	  /* there are 8 64bit floating point registers */

	  if (nf < 8)
	    {
	      temp = pfr->d;
	      pfr->f = (float) temp;
	      avalue[i] = pfr;
	      nf++;
	      pfr++;
	    }
	  else
	    {
	      /* FIXME? here we are really changing the values
	       * stored in the original calling routines outgoing
	       * parameter stack.  This is probably a really
	       * naughty thing to do but...
	       */
	      avalue[i] = pst;
	      pst += 1;
	    }
	  break;

	case FFI_TYPE_DOUBLE:
	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
	    goto soft_double_closure;
	  /* On the outgoing stack all values are aligned to 8 */
	  /* there are 8 64bit floating point registers */

	  if (nf < 8)
	    {
	      avalue[i] = pfr;
	      nf++;
	      pfr++;
	    }
	  else
	    {
	      if (((long) pst) & 4)
		pst++;
	      avalue[i] = pst;
	      pst += 2;
	    }
	  break;

#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	case FFI_TYPE_LONGDOUBLE:
	  if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
	    goto do_struct;
	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
	    { /* Test if for the whole long double, 4 gprs are available.
		 otherwise the stuff ends up on the stack.  */
	      if (ng < 5)
		{
		  avalue[i] = pgr;
		  pgr += 4;
		  ng += 4;
		}
	      else
		{
		  avalue[i] = pst;
		  pst += 4;
		}
	      break;
	    }
	  if (nf < 7)
	    {
	      avalue[i] = pfr;
	      pfr += 2;
	      nf += 2;
	    }
	  else
	    {
	      if (((long) pst) & 4)
		pst++;
	      avalue[i] = pst;
	      pst += 4;
	      nf = 8;
	    }
	  break;
#endif

	default:
	  FFI_ASSERT (0);
	}

      i++;
    }


  (closure->fun) (cif, rvalue, avalue, closure->user_data);

  /* Tell ffi_closure_SYSV how to perform return type promotions.
     Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
     we have to tell ffi_closure_SYSV how to treat them.  */
  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
      && size <= 8)
    return FFI_SYSV_TYPE_SMALL_STRUCT + size;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
	   && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
    return FFI_TYPE_STRUCT;
#endif
  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
     respectivley UINT64.  */
  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
    {
      switch (cif->rtype->type)
	{
	case FFI_TYPE_FLOAT:
	  return FFI_TYPE_UINT32;
	  break;
	case FFI_TYPE_DOUBLE:
	  return FFI_TYPE_UINT64;
	  break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	case FFI_TYPE_LONGDOUBLE:
	  return FFI_TYPE_UINT128;
	  break;
#endif
	default:
	  return cif->rtype->type;
	}
    }
  else
    {
      return cif->rtype->type;
    }
}

int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
					   unsigned long *, ffi_dblfl *);

int FFI_HIDDEN
ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
			    unsigned long *pst, ffi_dblfl *pfr)
{
  /* rvalue is the pointer to space for return value in closure assembly */
  /* pst is the pointer to parameter save area
     (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */

  void **avalue;
  ffi_type **arg_types;
  long i, avn;
  ffi_cif *cif;
  ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;

  cif = closure->cif;
  avalue = alloca (cif->nargs * sizeof (void *));

  /* Copy the caller's structure return value address so that the closure
     returns the data directly to the caller.  */
  if (cif->rtype->type == FFI_TYPE_STRUCT)
    {
      rvalue = (void *) *pst;
      pst++;
    }

  i = 0;
  avn = cif->nargs;
  arg_types = cif->arg_types;

  /* Grab the addresses of the arguments from the stack frame.  */
  while (i < avn)
    {
      switch (arg_types[i]->type)
	{
	case FFI_TYPE_SINT8:
	case FFI_TYPE_UINT8:
	  avalue[i] = (char *) pst + 7;
	  pst++;
	  break;

	case FFI_TYPE_SINT16:
	case FFI_TYPE_UINT16:
	  avalue[i] = (char *) pst + 6;
	  pst++;
	  break;

	case FFI_TYPE_SINT32:
	case FFI_TYPE_UINT32:
	  avalue[i] = (char *) pst + 4;
	  pst++;
	  break;

	case FFI_TYPE_SINT64:
	case FFI_TYPE_UINT64:
	case FFI_TYPE_POINTER:
	  avalue[i] = pst;
	  pst++;
	  break;

	case FFI_TYPE_STRUCT:
	  /* Structures with size less than eight bytes are passed
	     left-padded.  */
	  if (arg_types[i]->size < 8)
	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
	  else
	    avalue[i] = pst;
	  pst += (arg_types[i]->size + 7) / 8;
	  break;

	case FFI_TYPE_FLOAT:
	  /* unfortunately float values are stored as doubles
	   * in the ffi_closure_LINUX64 code (since we don't check
	   * the type in that routine).
	   */

	  /* there are 13 64bit floating point registers */

	  if (pfr < end_pfr)
	    {
	      double temp = pfr->d;
	      pfr->f = (float) temp;
	      avalue[i] = pfr;
	      pfr++;
	    }
	  else
	    avalue[i] = pst;
	  pst++;
	  break;

	case FFI_TYPE_DOUBLE:
	  /* On the outgoing stack all values are aligned to 8 */
	  /* there are 13 64bit floating point registers */

	  if (pfr < end_pfr)
	    {
	      avalue[i] = pfr;
	      pfr++;
	    }
	  else
	    avalue[i] = pst;
	  pst++;
	  break;

#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
	case FFI_TYPE_LONGDOUBLE:
	  if (pfr + 1 < end_pfr)
	    {
	      avalue[i] = pfr;
	      pfr += 2;
	    }
	  else
	    {
	      if (pfr < end_pfr)
		{
		  /* Passed partly in f13 and partly on the stack.
		     Move it all to the stack.  */
		  *pst = *(unsigned long *) pfr;
		  pfr++;
		}
	      avalue[i] = pst;
	    }
	  pst += 2;
	  break;
#endif

	default:
	  FFI_ASSERT (0);
	}

      i++;
    }


  (closure->fun) (cif, rvalue, avalue, closure->user_data);

  /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
  return cif->rtype->type;
}
