libffi-ppc64le.patch
branchesr24
changeset 713 3c7719dfcafa
parent 706 4639b5ad4fce
child 728 6820714d53f4
equal deleted inserted replaced
706:4639b5ad4fce 713:3c7719dfcafa
     1 --- mozilla/js/src/ctypes/libffi/src/powerpc/aix.S	2013-10-24 09:56:51.844587814 +0200
       
     2 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/aix.S	2013-11-29 17:23:26.000000000 +0100
       
     3 @@ -1,5 +1,5 @@
       
     4  /* -----------------------------------------------------------------------
       
     5 -   aix.S - Copyright (c) 2002,2009 Free Software Foundation, Inc.
       
     6 +   aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc.
       
     7     based on darwin.S by John Hornkvist
       
     8  
       
     9     PowerPC Assembly glue.
       
    10 @@ -79,6 +79,8 @@
       
    11  	.set f20,20
       
    12  	.set f21,21
       
    13  
       
    14 +	.extern .ffi_prep_args
       
    15 +
       
    16  #define LIBFFI_ASM
       
    17  #include <fficonfig.h>
       
    18  #include <ffi.h>
       
    19 @@ -125,6 +127,7 @@ ffi_call_AIX:
       
    20  	/* Call ffi_prep_args.  */
       
    21  	mr	r4, r1
       
    22  	bl	.ffi_prep_args
       
    23 +	nop
       
    24  
       
    25  	/* Now do the call.  */
       
    26  	ld	r0, 0(r29)
       
    27 @@ -226,6 +229,7 @@ L(float_return_value):
       
    28  	/* Call ffi_prep_args.  */
       
    29  	mr	r4, r1
       
    30  	bl	.ffi_prep_args
       
    31 +	nop
       
    32  
       
    33  	/* Now do the call.  */
       
    34  	lwz	r0, 0(r29)
       
    35 --- mozilla/js/src/ctypes/libffi/src/powerpc/ffi.c	2013-10-24 09:56:51.846587814 +0200
       
    36 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/ffi.c	2013-11-29 17:23:26.000000000 +0100
       
    37 @@ -1,7 +1,9 @@
       
    38  /* -----------------------------------------------------------------------
       
    39 -   ffi.c - Copyright (c) 1998 Geoffrey Keating
       
    40 -   Copyright (C) 2007, 2008 Free Software Foundation, Inc
       
    41 -   Copyright (C) 2008 Red Hat, Inc
       
    42 +   ffi.c - Copyright (C) 2011 Anthony Green
       
    43 +           Copyright (C) 2011 Kyle Moffett
       
    44 +           Copyright (C) 2008 Red Hat, Inc
       
    45 +           Copyright (C) 2007, 2008 Free Software Foundation, Inc
       
    46 +	   Copyright (c) 1998 Geoffrey Keating
       
    47  
       
    48     PowerPC Foreign Function Interface
       
    49  
       
    50 @@ -39,32 +41,29 @@ enum {
       
    51    /* The assembly depends on these exact flags.  */
       
    52    FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
       
    53    FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
       
    54 +#ifndef __NO_FPRS__
       
    55    FLAG_RETURNS_FP       = 1 << (31-29),
       
    56 +#endif
       
    57    FLAG_RETURNS_64BITS   = 1 << (31-28),
       
    58  
       
    59    FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
       
    60 -  FLAG_SYSV_SMST_R4     = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
       
    61 -					   structs.  */
       
    62 -  FLAG_SYSV_SMST_R3     = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
       
    63 -					   structs.  */
       
    64 -  /* Bits (31-24) through (31-19) store shift value for SMST */
       
    65  
       
    66    FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
       
    67 +  FLAG_ARG_NEEDS_PSAVE  = FLAG_ARG_NEEDS_COPY, /* Used by ELFv2 */
       
    68 +#ifndef __NO_FPRS__
       
    69    FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
       
    70 +#endif
       
    71    FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
       
    72    FLAG_RETVAL_REFERENCE = 1 << (31- 4)
       
    73  };
       
    74  
       
    75  /* About the SYSV ABI.  */
       
    76 -unsigned int NUM_GPR_ARG_REGISTERS = 8;
       
    77 +#define ASM_NEEDS_REGISTERS 4
       
    78 +#define NUM_GPR_ARG_REGISTERS 8
       
    79  #ifndef __NO_FPRS__
       
    80 -unsigned int NUM_FPR_ARG_REGISTERS = 8;
       
    81 -#else
       
    82 -unsigned int NUM_FPR_ARG_REGISTERS = 0;
       
    83 +# define NUM_FPR_ARG_REGISTERS 8
       
    84  #endif
       
    85  
       
    86 -enum { ASM_NEEDS_REGISTERS = 4 };
       
    87 -
       
    88  /* ffi_prep_args_SYSV is called by the assembly routine once stack space
       
    89     has been allocated for the function's arguments.
       
    90  
       
    91 @@ -113,10 +112,12 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
    92    valp gpr_base;
       
    93    int intarg_count;
       
    94  
       
    95 +#ifndef __NO_FPRS__
       
    96    /* 'fpr_base' points at the space for fpr1, and grows upwards as
       
    97       we use FPR registers.  */
       
    98    valp fpr_base;
       
    99    int fparg_count;
       
   100 +#endif
       
   101  
       
   102    /* 'copy_space' grows down as we put structures in it.  It should
       
   103       stay 16-byte aligned.  */
       
   104 @@ -125,9 +126,11 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   105    /* 'next_arg' grows up as we put parameters in it.  */
       
   106    valp next_arg;
       
   107  
       
   108 -  int i, ii MAYBE_UNUSED;
       
   109 +  int i;
       
   110    ffi_type **ptr;
       
   111 +#ifndef __NO_FPRS__
       
   112    double double_tmp;
       
   113 +#endif
       
   114    union {
       
   115      void **v;
       
   116      char **c;
       
   117 @@ -143,21 +146,22 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   118    size_t struct_copy_size;
       
   119    unsigned gprvalue;
       
   120  
       
   121 -  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   122 -    NUM_FPR_ARG_REGISTERS = 0;
       
   123 -
       
   124    stacktop.c = (char *) stack + bytes;
       
   125    gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
       
   126    intarg_count = 0;
       
   127 +#ifndef __NO_FPRS__
       
   128    fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
       
   129    fparg_count = 0;
       
   130    copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
       
   131 +#else
       
   132 +  copy_space.c = gpr_base.c;
       
   133 +#endif
       
   134    next_arg.u = stack + 2;
       
   135  
       
   136    /* Check that everything starts aligned properly.  */
       
   137 -  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
       
   138 -  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
       
   139 -  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
       
   140 +  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
       
   141 +  FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
       
   142 +  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
       
   143    FFI_ASSERT ((bytes & 0xF) == 0);
       
   144    FFI_ASSERT (copy_space.c >= next_arg.c);
       
   145  
       
   146 @@ -174,12 +178,28 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   147         i > 0;
       
   148         i--, ptr++, p_argv.v++)
       
   149      {
       
   150 -      switch ((*ptr)->type)
       
   151 -	{
       
   152 +      unsigned short typenum = (*ptr)->type;
       
   153 +
       
   154 +      /* We may need to handle some values depending on ABI */
       
   155 +      if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) {
       
   156 +		if (typenum == FFI_TYPE_FLOAT)
       
   157 +			typenum = FFI_TYPE_UINT32;
       
   158 +		if (typenum == FFI_TYPE_DOUBLE)
       
   159 +			typenum = FFI_TYPE_UINT64;
       
   160 +		if (typenum == FFI_TYPE_LONGDOUBLE)
       
   161 +			typenum = FFI_TYPE_UINT128;
       
   162 +      } else if (ecif->cif->abi != FFI_LINUX) {
       
   163 +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   164 +		if (typenum == FFI_TYPE_LONGDOUBLE)
       
   165 +			typenum = FFI_TYPE_STRUCT;
       
   166 +#endif
       
   167 +      }
       
   168 +
       
   169 +      /* Now test the translated value */
       
   170 +      switch (typenum) {
       
   171 +#ifndef __NO_FPRS__
       
   172  	case FFI_TYPE_FLOAT:
       
   173  	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
       
   174 -	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   175 -	    goto soft_float_prep;
       
   176  	  double_tmp = **p_argv.f;
       
   177  	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
       
   178  	    {
       
   179 @@ -195,8 +215,6 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   180  
       
   181  	case FFI_TYPE_DOUBLE:
       
   182  	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
       
   183 -	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   184 -	    goto soft_double_prep;
       
   185  	  double_tmp = **p_argv.d;
       
   186  
       
   187  	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
       
   188 @@ -218,43 +236,6 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   189  
       
   190  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   191  	case FFI_TYPE_LONGDOUBLE:
       
   192 -	  if ((ecif->cif->abi != FFI_LINUX)
       
   193 -		&& (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
       
   194 -	    goto do_struct;
       
   195 -	  /* The soft float ABI for long doubles works like this,
       
   196 -	     a long double is passed in four consecutive gprs if available.
       
   197 -	     A maximum of 2 long doubles can be passed in gprs.
       
   198 -	     If we do not have 4 gprs left, the long double is passed on the
       
   199 -	     stack, 4-byte aligned.  */
       
   200 -	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   201 -	    {
       
   202 -	      unsigned int int_tmp = (*p_argv.ui)[0];
       
   203 -	      if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
       
   204 -		{
       
   205 -		  if (intarg_count < NUM_GPR_ARG_REGISTERS)
       
   206 -		    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
       
   207 -		  *next_arg.u = int_tmp;
       
   208 -		  next_arg.u++;
       
   209 -		  for (ii = 1; ii < 4; ii++)
       
   210 -		    {
       
   211 -		      int_tmp = (*p_argv.ui)[ii];
       
   212 -		      *next_arg.u = int_tmp;
       
   213 -		      next_arg.u++;
       
   214 -		    }
       
   215 -		}
       
   216 -	      else
       
   217 -		{
       
   218 -		  *gpr_base.u++ = int_tmp;
       
   219 -		  for (ii = 1; ii < 4; ii++)
       
   220 -		    {
       
   221 -		      int_tmp = (*p_argv.ui)[ii];
       
   222 -		      *gpr_base.u++ = int_tmp;
       
   223 -		    }
       
   224 -		}
       
   225 -	      intarg_count +=4;
       
   226 -	    }
       
   227 -	  else
       
   228 -	    {
       
   229  	      double_tmp = (*p_argv.d)[0];
       
   230  
       
   231  	      if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
       
   232 @@ -280,13 +261,40 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   233  
       
   234  	      fparg_count += 2;
       
   235  	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
       
   236 -	    }
       
   237  	  break;
       
   238  #endif
       
   239 +#endif /* have FPRs */
       
   240 +
       
   241 +	/*
       
   242 +	 * The soft float ABI for long doubles works like this, a long double
       
   243 +	 * is passed in four consecutive GPRs if available.  A maximum of 2
       
   244 +	 * long doubles can be passed in gprs.  If we do not have 4 GPRs
       
   245 +	 * left, the long double is passed on the stack, 4-byte aligned.
       
   246 +	 */
       
   247 +	case FFI_TYPE_UINT128: {
       
   248 +		unsigned int int_tmp = (*p_argv.ui)[0];
       
   249 +		unsigned int ii;
       
   250 +		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) {
       
   251 +			if (intarg_count < NUM_GPR_ARG_REGISTERS)
       
   252 +				intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
       
   253 +			*(next_arg.u++) = int_tmp;
       
   254 +			for (ii = 1; ii < 4; ii++) {
       
   255 +				int_tmp = (*p_argv.ui)[ii];
       
   256 +				*(next_arg.u++) = int_tmp;
       
   257 +			}
       
   258 +		} else {
       
   259 +			*(gpr_base.u++) = int_tmp;
       
   260 +			for (ii = 1; ii < 4; ii++) {
       
   261 +				int_tmp = (*p_argv.ui)[ii];
       
   262 +				*(gpr_base.u++) = int_tmp;
       
   263 +			}
       
   264 +		}
       
   265 +		intarg_count += 4;
       
   266 +		break;
       
   267 +	}
       
   268  
       
   269  	case FFI_TYPE_UINT64:
       
   270  	case FFI_TYPE_SINT64:
       
   271 -	soft_double_prep:
       
   272  	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
       
   273  	    intarg_count++;
       
   274  	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
       
   275 @@ -319,9 +327,6 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   276  	  break;
       
   277  
       
   278  	case FFI_TYPE_STRUCT:
       
   279 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   280 -	do_struct:
       
   281 -#endif
       
   282  	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
       
   283  	  copy_space.c -= struct_copy_size;
       
   284  	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
       
   285 @@ -349,7 +354,6 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   286  	case FFI_TYPE_UINT32:
       
   287  	case FFI_TYPE_SINT32:
       
   288  	case FFI_TYPE_POINTER:
       
   289 -	soft_float_prep:
       
   290  
       
   291  	  gprvalue = **p_argv.ui;
       
   292  
       
   293 @@ -366,8 +370,16 @@ ffi_prep_args_SYSV (extended_cif *ecif,
       
   294    /* Check that we didn't overrun the stack...  */
       
   295    FFI_ASSERT (copy_space.c >= next_arg.c);
       
   296    FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
       
   297 +  /* The assert below is testing that the number of integer arguments agrees
       
   298 +     with the number found in ffi_prep_cif_machdep().  However, intarg_count
       
   299 +     is incremented whenever we place an FP arg on the stack, so account for
       
   300 +     that before our assert test.  */
       
   301 +#ifndef __NO_FPRS__
       
   302 +  if (fparg_count > NUM_FPR_ARG_REGISTERS)
       
   303 +    intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS;
       
   304    FFI_ASSERT (fpr_base.u
       
   305  	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
       
   306 +#endif
       
   307    FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
       
   308  }
       
   309  
       
   310 @@ -378,6 +390,45 @@ enum {
       
   311  };
       
   312  enum { ASM_NEEDS_REGISTERS64 = 4 };
       
   313  
       
   314 +#if _CALL_ELF == 2
       
   315 +static unsigned int
       
   316 +discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
       
   317 +{
       
   318 +  switch (t->type)
       
   319 +    {
       
   320 +    case FFI_TYPE_FLOAT:
       
   321 +    case FFI_TYPE_DOUBLE:
       
   322 +      *elnum = 1;
       
   323 +      return (int) t->type;
       
   324 +
       
   325 +    case FFI_TYPE_STRUCT:;
       
   326 +      {
       
   327 +	unsigned int base_elt = 0, total_elnum = 0;
       
   328 +	ffi_type **el = t->elements;
       
   329 +	while (*el)
       
   330 +	  {
       
   331 +	    unsigned int el_elt, el_elnum = 0;
       
   332 +	    el_elt = discover_homogeneous_aggregate (*el, &el_elnum);
       
   333 +	    if (el_elt == 0
       
   334 +		|| (base_elt && base_elt != el_elt))
       
   335 +	      return 0;
       
   336 +	    base_elt = el_elt;
       
   337 +	    total_elnum += el_elnum;
       
   338 +	    if (total_elnum > 8)
       
   339 +	      return 0;
       
   340 +	    el++;
       
   341 +	  }
       
   342 +	*elnum = total_elnum;
       
   343 +	return base_elt;
       
   344 +      }
       
   345 +
       
   346 +    default:
       
   347 +      return 0;
       
   348 +    }
       
   349 +}
       
   350 +#endif
       
   351 +
       
   352 +
       
   353  /* ffi_prep_args64 is called by the assembly routine once stack space
       
   354     has been allocated for the function's arguments.
       
   355  
       
   356 @@ -423,6 +474,7 @@ ffi_prep_args64 (extended_cif *ecif, uns
       
   357      unsigned long *ul;
       
   358      float *f;
       
   359      double *d;
       
   360 +    size_t p;
       
   361    } valp;
       
   362  
       
   363    /* 'stacktop' points at the previous backchain pointer.  */
       
   364 @@ -438,9 +490,9 @@ ffi_prep_args64 (extended_cif *ecif, uns
       
   365    /* 'fpr_base' points at the space for fpr3, and grows upwards as
       
   366       we use FPR registers.  */
       
   367    valp fpr_base;
       
   368 -  int fparg_count;
       
   369 +  unsigned int fparg_count;
       
   370  
       
   371 -  int i, words;
       
   372 +  unsigned int i, words, nargs, nfixedargs;
       
   373    ffi_type **ptr;
       
   374    double double_tmp;
       
   375    union {
       
   376 @@ -457,11 +509,18 @@ ffi_prep_args64 (extended_cif *ecif, uns
       
   377      double **d;
       
   378    } p_argv;
       
   379    unsigned long gprvalue;
       
   380 +#ifdef __STRUCT_PARM_ALIGN__
       
   381 +  unsigned long align;
       
   382 +#endif
       
   383  
       
   384    stacktop.c = (char *) stack + bytes;
       
   385    gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
       
   386    gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
       
   387 +#if _CALL_ELF == 2
       
   388 +  rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64;
       
   389 +#else
       
   390    rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
       
   391 +#endif
       
   392    fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
       
   393    fparg_count = 0;
       
   394    next_arg.ul = gpr_base.ul;
       
   395 @@ -477,30 +536,36 @@ ffi_prep_args64 (extended_cif *ecif, uns
       
   396  
       
   397    /* Now for the arguments.  */
       
   398    p_argv.v = ecif->avalue;
       
   399 -  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
       
   400 -       i > 0;
       
   401 -       i--, ptr++, p_argv.v++)
       
   402 +  nargs = ecif->cif->nargs;
       
   403 +  nfixedargs = ecif->cif->nfixedargs;
       
   404 +  for (ptr = ecif->cif->arg_types, i = 0;
       
   405 +       i < nargs;
       
   406 +       i++, ptr++, p_argv.v++)
       
   407      {
       
   408 +      unsigned int elt, elnum;
       
   409 +
       
   410        switch ((*ptr)->type)
       
   411  	{
       
   412  	case FFI_TYPE_FLOAT:
       
   413  	  double_tmp = **p_argv.f;
       
   414 -	  *next_arg.f = (float) double_tmp;
       
   415 +	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
       
   416 +	    *fpr_base.d++ = double_tmp;
       
   417 +	  else
       
   418 +	    *next_arg.f = (float) double_tmp;
       
   419  	  if (++next_arg.ul == gpr_end.ul)
       
   420  	    next_arg.ul = rest.ul;
       
   421 -	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
       
   422 -	    *fpr_base.d++ = double_tmp;
       
   423  	  fparg_count++;
       
   424  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
       
   425  	  break;
       
   426  
       
   427  	case FFI_TYPE_DOUBLE:
       
   428  	  double_tmp = **p_argv.d;
       
   429 -	  *next_arg.d = double_tmp;
       
   430 +	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
       
   431 +	    *fpr_base.d++ = double_tmp;
       
   432 +	  else
       
   433 +	    *next_arg.d = double_tmp;
       
   434  	  if (++next_arg.ul == gpr_end.ul)
       
   435  	    next_arg.ul = rest.ul;
       
   436 -	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
       
   437 -	    *fpr_base.d++ = double_tmp;
       
   438  	  fparg_count++;
       
   439  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
       
   440  	  break;
       
   441 @@ -508,18 +573,20 @@ ffi_prep_args64 (extended_cif *ecif, uns
       
   442  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   443  	case FFI_TYPE_LONGDOUBLE:
       
   444  	  double_tmp = (*p_argv.d)[0];
       
   445 -	  *next_arg.d = double_tmp;
       
   446 +	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
       
   447 +	    *fpr_base.d++ = double_tmp;
       
   448 +	  else
       
   449 +	    *next_arg.d = double_tmp;
       
   450  	  if (++next_arg.ul == gpr_end.ul)
       
   451  	    next_arg.ul = rest.ul;
       
   452 -	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
       
   453 -	    *fpr_base.d++ = double_tmp;
       
   454  	  fparg_count++;
       
   455  	  double_tmp = (*p_argv.d)[1];
       
   456 -	  *next_arg.d = double_tmp;
       
   457 +	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
       
   458 +	    *fpr_base.d++ = double_tmp;
       
   459 +	  else
       
   460 +	    *next_arg.d = double_tmp;
       
   461  	  if (++next_arg.ul == gpr_end.ul)
       
   462  	    next_arg.ul = rest.ul;
       
   463 -	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
       
   464 -	    *fpr_base.d++ = double_tmp;
       
   465  	  fparg_count++;
       
   466  	  FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
       
   467  	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
       
   468 @@ -527,27 +594,86 @@ ffi_prep_args64 (extended_cif *ecif, uns
       
   469  #endif
       
   470  
       
   471  	case FFI_TYPE_STRUCT:
       
   472 -	  words = ((*ptr)->size + 7) / 8;
       
   473 -	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
       
   474 +#ifdef __STRUCT_PARM_ALIGN__
       
   475 +	  align = (*ptr)->alignment;
       
   476 +	  if (align > __STRUCT_PARM_ALIGN__)
       
   477 +	    align = __STRUCT_PARM_ALIGN__;
       
   478 +	  if (align > 1)
       
   479 +	    next_arg.p = ALIGN (next_arg.p, align);
       
   480 +#endif
       
   481 +	  elt = 0;
       
   482 +#if _CALL_ELF == 2
       
   483 +	  elt = discover_homogeneous_aggregate (*ptr, &elnum);
       
   484 +#endif
       
   485 +	  if (elt)
       
   486  	    {
       
   487 -	      size_t first = gpr_end.c - next_arg.c;
       
   488 -	      memcpy (next_arg.c, *p_argv.c, first);
       
   489 -	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
       
   490 -	      next_arg.c = rest.c + words * 8 - first;
       
   491 +	      union {
       
   492 +		void *v;
       
   493 +		float *f;
       
   494 +		double *d;
       
   495 +	      } arg;
       
   496 +
       
   497 +	      arg.v = *p_argv.v;
       
   498 +	      if (elt == FFI_TYPE_FLOAT)
       
   499 +		{
       
   500 +		  do
       
   501 +		    {
       
   502 +		      double_tmp = *arg.f++;
       
   503 +		      if (fparg_count < NUM_FPR_ARG_REGISTERS64
       
   504 +			  && i < nfixedargs)
       
   505 +			*fpr_base.d++ = double_tmp;
       
   506 +		      else
       
   507 +			*next_arg.f = (float) double_tmp;
       
   508 +		      if (++next_arg.f == gpr_end.f)
       
   509 +			next_arg.f = rest.f;
       
   510 +		      fparg_count++;
       
   511 +		    }
       
   512 +		  while (--elnum != 0);
       
   513 +		  if ((next_arg.p & 3) != 0)
       
   514 +		    {
       
   515 +		      if (++next_arg.f == gpr_end.f)
       
   516 +			next_arg.f = rest.f;
       
   517 +		    }
       
   518 +		}
       
   519 +	      else
       
   520 +		do
       
   521 +		  {
       
   522 +		    double_tmp = *arg.d++;
       
   523 +		    if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
       
   524 +		      *fpr_base.d++ = double_tmp;
       
   525 +		    else
       
   526 +		      *next_arg.d = double_tmp;
       
   527 +		    if (++next_arg.d == gpr_end.d)
       
   528 +		      next_arg.d = rest.d;
       
   529 +		    fparg_count++;
       
   530 +		  }
       
   531 +		while (--elnum != 0);
       
   532  	    }
       
   533  	  else
       
   534  	    {
       
   535 -	      char *where = next_arg.c;
       
   536 -
       
   537 -	      /* Structures with size less than eight bytes are passed
       
   538 -		 left-padded.  */
       
   539 -	      if ((*ptr)->size < 8)
       
   540 -		where += 8 - (*ptr)->size;
       
   541 +	      words = ((*ptr)->size + 7) / 8;
       
   542 +	      if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
       
   543 +		{
       
   544 +		  size_t first = gpr_end.c - next_arg.c;
       
   545 +		  memcpy (next_arg.c, *p_argv.c, first);
       
   546 +		  memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
       
   547 +		  next_arg.c = rest.c + words * 8 - first;
       
   548 +		}
       
   549 +	      else
       
   550 +		{
       
   551 +		  char *where = next_arg.c;
       
   552  
       
   553 -	      memcpy (where, *p_argv.c, (*ptr)->size);
       
   554 -	      next_arg.ul += words;
       
   555 -	      if (next_arg.ul == gpr_end.ul)
       
   556 -		next_arg.ul = rest.ul;
       
   557 +#ifndef __LITTLE_ENDIAN__
       
   558 +		  /* Structures with size less than eight bytes are passed
       
   559 +		     left-padded.  */
       
   560 +		  if ((*ptr)->size < 8)
       
   561 +		    where += 8 - (*ptr)->size;
       
   562 +#endif
       
   563 +		  memcpy (where, *p_argv.c, (*ptr)->size);
       
   564 +		  next_arg.ul += words;
       
   565 +		  if (next_arg.ul == gpr_end.ul)
       
   566 +		    next_arg.ul = rest.ul;
       
   567 +		}
       
   568  	    }
       
   569  	  break;
       
   570  
       
   571 @@ -591,27 +717,22 @@ ffi_prep_args64 (extended_cif *ecif, uns
       
   572  
       
   573  
       
   574  /* Perform machine dependent cif processing */
       
   575 -ffi_status
       
   576 -ffi_prep_cif_machdep (ffi_cif *cif)
       
   577 +static ffi_status
       
   578 +ffi_prep_cif_machdep_core (ffi_cif *cif)
       
   579  {
       
   580    /* All this is for the SYSV and LINUX64 ABI.  */
       
   581 -  int i;
       
   582    ffi_type **ptr;
       
   583    unsigned bytes;
       
   584 -  int fparg_count = 0, intarg_count = 0;
       
   585 -  unsigned flags = 0;
       
   586 +  unsigned i, fparg_count = 0, intarg_count = 0;
       
   587 +  unsigned flags = cif->flags;
       
   588    unsigned struct_copy_size = 0;
       
   589    unsigned type = cif->rtype->type;
       
   590    unsigned size = cif->rtype->size;
       
   591  
       
   592 -  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   593 -    NUM_FPR_ARG_REGISTERS = 0;
       
   594 -
       
   595 +  /* The machine-independent calculation of cif->bytes doesn't work
       
   596 +     for us.  Redo the calculation.  */
       
   597    if (cif->abi != FFI_LINUX64)
       
   598      {
       
   599 -      /* All the machine-independent calculation of cif->bytes will be wrong.
       
   600 -	 Redo the calculation for SYSV.  */
       
   601 -
       
   602        /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
       
   603        bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
       
   604  
       
   605 @@ -621,13 +742,20 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   606    else
       
   607      {
       
   608        /* 64-bit ABI.  */
       
   609 +#if _CALL_ELF == 2
       
   610 +      /* Space for backchain, CR, LR, TOC and the asm's temp regs.  */
       
   611 +      bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long);
       
   612  
       
   613 +      /* Space for the general registers.  */
       
   614 +      bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long);
       
   615 +#else
       
   616        /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
       
   617  	 regs.  */
       
   618        bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
       
   619  
       
   620        /* Space for the mandatory parm save area and general registers.  */
       
   621        bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
       
   622 +#endif
       
   623      }
       
   624  
       
   625    /* Return value handling.  The rules for SYSV are as follows:
       
   626 @@ -646,13 +774,30 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   627       - Single/double FP values in fpr1, long double in fpr1,fpr2.
       
   628       - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
       
   629       - soft-float long doubles are returned in gpr3-gpr6.  */
       
   630 +  /* First translate for softfloat/nonlinux */
       
   631 +  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   632 +    {
       
   633 +      if (type == FFI_TYPE_FLOAT)
       
   634 +	type = FFI_TYPE_UINT32;
       
   635 +      if (type == FFI_TYPE_DOUBLE)
       
   636 +	type = FFI_TYPE_UINT64;
       
   637 +      if (type == FFI_TYPE_LONGDOUBLE)
       
   638 +	type = FFI_TYPE_UINT128;
       
   639 +    }
       
   640 +  else if (cif->abi != FFI_LINUX
       
   641 +	   && cif->abi != FFI_LINUX64)
       
   642 +    {
       
   643 +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   644 +      if (type == FFI_TYPE_LONGDOUBLE)
       
   645 +	type = FFI_TYPE_STRUCT;
       
   646 +#endif
       
   647 +    }
       
   648 +
       
   649    switch (type)
       
   650      {
       
   651 +#ifndef __NO_FPRS__
       
   652  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   653      case FFI_TYPE_LONGDOUBLE:
       
   654 -      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
       
   655 -	&& cif->abi != FFI_LINUX_SOFT_FLOAT)
       
   656 -	goto byref;
       
   657        flags |= FLAG_RETURNS_128BITS;
       
   658        /* Fall through.  */
       
   659  #endif
       
   660 @@ -660,47 +805,52 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   661        flags |= FLAG_RETURNS_64BITS;
       
   662        /* Fall through.  */
       
   663      case FFI_TYPE_FLOAT:
       
   664 -      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
       
   665 -      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
       
   666 -	flags |= FLAG_RETURNS_FP;
       
   667 +      flags |= FLAG_RETURNS_FP;
       
   668        break;
       
   669 +#endif
       
   670  
       
   671 +    case FFI_TYPE_UINT128:
       
   672 +      flags |= FLAG_RETURNS_128BITS;
       
   673 +      /* Fall through.  */
       
   674      case FFI_TYPE_UINT64:
       
   675      case FFI_TYPE_SINT64:
       
   676        flags |= FLAG_RETURNS_64BITS;
       
   677        break;
       
   678  
       
   679      case FFI_TYPE_STRUCT:
       
   680 -      if (cif->abi == FFI_SYSV)
       
   681 +      /*
       
   682 +       * The final SYSV ABI says that structures smaller or equal 8 bytes
       
   683 +       * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
       
   684 +       * in memory.
       
   685 +       *
       
   686 +       * NOTE: The assembly code can safely assume that it just needs to
       
   687 +       *       store both r3 and r4 into a 8-byte word-aligned buffer, as
       
   688 +       *       we allocate a temporary buffer in ffi_call() if this flag is
       
   689 +       *       set.
       
   690 +       */
       
   691 +      if (cif->abi == FFI_SYSV && size <= 8)
       
   692  	{
       
   693 -	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
       
   694 -	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
       
   695 -	     in memory.  */
       
   696 -
       
   697 -	  /* Treat structs with size <= 8 bytes.  */
       
   698 -	  if (size <= 8)
       
   699 +	  flags |= FLAG_RETURNS_SMST;
       
   700 +	  break;
       
   701 +	}
       
   702 +#if _CALL_ELF == 2
       
   703 +      if (cif->abi == FFI_LINUX64)
       
   704 +	{
       
   705 +	  unsigned int elt, elnum;
       
   706 +	  elt = discover_homogeneous_aggregate (cif->rtype, &elnum);
       
   707 +	  if (elt)
       
   708 +	    {
       
   709 +	      if (elt == FFI_TYPE_DOUBLE)
       
   710 +		flags |= FLAG_RETURNS_64BITS;
       
   711 +	      flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST;
       
   712 +	      break;
       
   713 +	    }
       
   714 +	  if (size <= 16)
       
   715  	    {
       
   716  	      flags |= FLAG_RETURNS_SMST;
       
   717 -	      /* These structs are returned in r3. We pack the type and the
       
   718 -		 precalculated shift value (needed in the sysv.S) into flags.
       
   719 -		 The same applies for the structs returned in r3/r4.  */
       
   720 -	      if (size <= 4)
       
   721 -		{
       
   722 -		  flags |= FLAG_SYSV_SMST_R3;
       
   723 -		  flags |= 8 * (4 - size) << 8;
       
   724 -		  break;
       
   725 -		}
       
   726 -	      /* These structs are returned in r3 and r4. See above.   */
       
   727 -	      if  (size <= 8)
       
   728 -		{
       
   729 -		  flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
       
   730 -		  flags |= 8 * (8 - size) << 8;
       
   731 -		  break;
       
   732 -		}
       
   733 +	      break;
       
   734  	    }
       
   735  	}
       
   736 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   737 -    byref:
       
   738  #endif
       
   739        intarg_count++;
       
   740        flags |= FLAG_RETVAL_REFERENCE;
       
   741 @@ -722,39 +872,36 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   742         Stuff on the stack needs to keep proper alignment.  */
       
   743      for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
       
   744        {
       
   745 -	switch ((*ptr)->type)
       
   746 -	  {
       
   747 +	unsigned short typenum = (*ptr)->type;
       
   748 +
       
   749 +	/* We may need to handle some values depending on ABI */
       
   750 +	if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
       
   751 +		if (typenum == FFI_TYPE_FLOAT)
       
   752 +			typenum = FFI_TYPE_UINT32;
       
   753 +		if (typenum == FFI_TYPE_DOUBLE)
       
   754 +			typenum = FFI_TYPE_UINT64;
       
   755 +		if (typenum == FFI_TYPE_LONGDOUBLE)
       
   756 +			typenum = FFI_TYPE_UINT128;
       
   757 +	} else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
       
   758 +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   759 +		if (typenum == FFI_TYPE_LONGDOUBLE)
       
   760 +			typenum = FFI_TYPE_STRUCT;
       
   761 +#endif
       
   762 +	}
       
   763 +
       
   764 +	switch (typenum) {
       
   765 +#ifndef __NO_FPRS__
       
   766  	  case FFI_TYPE_FLOAT:
       
   767 -	    /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
       
   768 -	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   769 -	      goto soft_float_cif;
       
   770  	    fparg_count++;
       
   771  	    /* floating singles are not 8-aligned on stack */
       
   772  	    break;
       
   773  
       
   774  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   775  	  case FFI_TYPE_LONGDOUBLE:
       
   776 -	    if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
       
   777 -	      goto do_struct;
       
   778 -	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   779 -	      {
       
   780 -		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
       
   781 -		  || intarg_count < NUM_GPR_ARG_REGISTERS)
       
   782 -		  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
       
   783 -		     a set of four consecutive gprs. If we have not enough,
       
   784 -		     we have to adjust the intarg_count value.  */
       
   785 -		  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
       
   786 -		intarg_count += 4;
       
   787 -		break;
       
   788 -	      }
       
   789 -	    else
       
   790 -	      fparg_count++;
       
   791 +	    fparg_count++;
       
   792  	    /* Fall thru */
       
   793  #endif
       
   794  	  case FFI_TYPE_DOUBLE:
       
   795 -	    /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
       
   796 -	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   797 -	      goto soft_double_cif;
       
   798  	    fparg_count++;
       
   799  	    /* If this FP arg is going on the stack, it must be
       
   800  	       8-byte-aligned.  */
       
   801 @@ -763,10 +910,21 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   802  		&& intarg_count % 2 != 0)
       
   803  	      intarg_count++;
       
   804  	    break;
       
   805 +#endif
       
   806 +	  case FFI_TYPE_UINT128:
       
   807 +		/*
       
   808 +		 * A long double in FFI_LINUX_SOFT_FLOAT can use only a set
       
   809 +		 * of four consecutive gprs. If we do not have enough, we
       
   810 +		 * have to adjust the intarg_count value.
       
   811 +		 */
       
   812 +		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
       
   813 +				&& intarg_count < NUM_GPR_ARG_REGISTERS)
       
   814 +			intarg_count = NUM_GPR_ARG_REGISTERS;
       
   815 +		intarg_count += 4;
       
   816 +		break;
       
   817  
       
   818  	  case FFI_TYPE_UINT64:
       
   819  	  case FFI_TYPE_SINT64:
       
   820 -	  soft_double_cif:
       
   821  	    /* 'long long' arguments are passed as two words, but
       
   822  	       either both words must fit in registers or both go
       
   823  	       on the stack.  If they go on the stack, they must
       
   824 @@ -783,9 +941,6 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   825  	    break;
       
   826  
       
   827  	  case FFI_TYPE_STRUCT:
       
   828 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   829 -	  do_struct:
       
   830 -#endif
       
   831  	    /* We must allocate space for a copy of these to enforce
       
   832  	       pass-by-value.  Pad the space up to a multiple of 16
       
   833  	       bytes (the maximum alignment required for anything under
       
   834 @@ -793,50 +948,100 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   835  	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
       
   836  	    /* Fall through (allocate space for the pointer).  */
       
   837  
       
   838 -	  default:
       
   839 -	  soft_float_cif:
       
   840 +	  case FFI_TYPE_POINTER:
       
   841 +	  case FFI_TYPE_INT:
       
   842 +	  case FFI_TYPE_UINT32:
       
   843 +	  case FFI_TYPE_SINT32:
       
   844 +	  case FFI_TYPE_UINT16:
       
   845 +	  case FFI_TYPE_SINT16:
       
   846 +	  case FFI_TYPE_UINT8:
       
   847 +	  case FFI_TYPE_SINT8:
       
   848  	    /* Everything else is passed as a 4-byte word in a GPR, either
       
   849  	       the object itself or a pointer to it.  */
       
   850  	    intarg_count++;
       
   851  	    break;
       
   852 +	  default:
       
   853 +		FFI_ASSERT (0);
       
   854  	  }
       
   855        }
       
   856    else
       
   857      for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
       
   858        {
       
   859 +	unsigned int elt, elnum;
       
   860 +#ifdef __STRUCT_PARM_ALIGN__
       
   861 +	unsigned int align;
       
   862 +#endif
       
   863 +
       
   864  	switch ((*ptr)->type)
       
   865  	  {
       
   866  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
   867  	  case FFI_TYPE_LONGDOUBLE:
       
   868 -	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
   869 -	      intarg_count += 4;
       
   870 -	    else
       
   871 -	      {
       
   872 -		fparg_count += 2;
       
   873 -		intarg_count += 2;
       
   874 -	      }
       
   875 +	    fparg_count += 2;
       
   876 +	    intarg_count += 2;
       
   877 +	    if (fparg_count > NUM_FPR_ARG_REGISTERS)
       
   878 +	      flags |= FLAG_ARG_NEEDS_PSAVE;
       
   879  	    break;
       
   880  #endif
       
   881  	  case FFI_TYPE_FLOAT:
       
   882  	  case FFI_TYPE_DOUBLE:
       
   883  	    fparg_count++;
       
   884  	    intarg_count++;
       
   885 +	    if (fparg_count > NUM_FPR_ARG_REGISTERS)
       
   886 +	      flags |= FLAG_ARG_NEEDS_PSAVE;
       
   887  	    break;
       
   888  
       
   889  	  case FFI_TYPE_STRUCT:
       
   890 +#ifdef __STRUCT_PARM_ALIGN__
       
   891 +	    align = (*ptr)->alignment;
       
   892 +	    if (align > __STRUCT_PARM_ALIGN__)
       
   893 +	      align = __STRUCT_PARM_ALIGN__;
       
   894 +	    align = align / 8;
       
   895 +	    if (align > 1)
       
   896 +	      intarg_count = ALIGN (intarg_count, align);
       
   897 +#endif
       
   898  	    intarg_count += ((*ptr)->size + 7) / 8;
       
   899 +	    elt = 0;
       
   900 +#if _CALL_ELF == 2
       
   901 +	    elt = discover_homogeneous_aggregate (*ptr, &elnum);
       
   902 +#endif
       
   903 +	    if (elt)
       
   904 +	      {
       
   905 +		fparg_count += elnum;
       
   906 +		if (fparg_count > NUM_FPR_ARG_REGISTERS)
       
   907 +		  flags |= FLAG_ARG_NEEDS_PSAVE;
       
   908 +	      }
       
   909 +	    else
       
   910 +	      {
       
   911 +		if (intarg_count > NUM_GPR_ARG_REGISTERS)
       
   912 +		  flags |= FLAG_ARG_NEEDS_PSAVE;
       
   913 +	      }
       
   914  	    break;
       
   915  
       
   916 -	  default:
       
   917 +	  case FFI_TYPE_POINTER:
       
   918 +	  case FFI_TYPE_UINT64:
       
   919 +	  case FFI_TYPE_SINT64:
       
   920 +	  case FFI_TYPE_INT:
       
   921 +	  case FFI_TYPE_UINT32:
       
   922 +	  case FFI_TYPE_SINT32:
       
   923 +	  case FFI_TYPE_UINT16:
       
   924 +	  case FFI_TYPE_SINT16:
       
   925 +	  case FFI_TYPE_UINT8:
       
   926 +	  case FFI_TYPE_SINT8:
       
   927  	    /* Everything else is passed as a 8-byte word in a GPR, either
       
   928  	       the object itself or a pointer to it.  */
       
   929  	    intarg_count++;
       
   930 +	    if (intarg_count > NUM_GPR_ARG_REGISTERS)
       
   931 +	      flags |= FLAG_ARG_NEEDS_PSAVE;
       
   932  	    break;
       
   933 +	  default:
       
   934 +	    FFI_ASSERT (0);
       
   935  	  }
       
   936        }
       
   937  
       
   938 +#ifndef __NO_FPRS__
       
   939    if (fparg_count != 0)
       
   940      flags |= FLAG_FP_ARGUMENTS;
       
   941 +#endif
       
   942    if (intarg_count > 4)
       
   943      flags |= FLAG_4_GPR_ARGUMENTS;
       
   944    if (struct_copy_size != 0)
       
   945 @@ -844,25 +1049,36 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   946  
       
   947    if (cif->abi != FFI_LINUX64)
       
   948      {
       
   949 +#ifndef __NO_FPRS__
       
   950        /* Space for the FPR registers, if needed.  */
       
   951        if (fparg_count != 0)
       
   952  	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
       
   953 +#endif
       
   954  
       
   955        /* Stack space.  */
       
   956        if (intarg_count > NUM_GPR_ARG_REGISTERS)
       
   957  	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
       
   958 +#ifndef __NO_FPRS__
       
   959        if (fparg_count > NUM_FPR_ARG_REGISTERS)
       
   960  	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
       
   961 +#endif
       
   962      }
       
   963    else
       
   964      {
       
   965 +#ifndef __NO_FPRS__
       
   966        /* Space for the FPR registers, if needed.  */
       
   967        if (fparg_count != 0)
       
   968  	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
       
   969 +#endif
       
   970  
       
   971        /* Stack space.  */
       
   972 +#if _CALL_ELF == 2
       
   973 +      if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0)
       
   974 +	bytes += intarg_count * sizeof (long);
       
   975 +#else
       
   976        if (intarg_count > NUM_GPR_ARG_REGISTERS64)
       
   977  	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
       
   978 +#endif
       
   979      }
       
   980  
       
   981    /* The stack space allocated needs to be a multiple of 16 bytes.  */
       
   982 @@ -877,6 +1093,26 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
   983    return FFI_OK;
       
   984  }
       
   985  
       
   986 +ffi_status
       
   987 +ffi_prep_cif_machdep (ffi_cif *cif)
       
   988 +{
       
   989 +  cif->nfixedargs = cif->nargs;
       
   990 +  return ffi_prep_cif_machdep_core (cif);
       
   991 +}
       
   992 +
       
   993 +ffi_status
       
   994 +ffi_prep_cif_machdep_var (ffi_cif *cif,
       
   995 +			  unsigned int nfixedargs,
       
   996 +			  unsigned int ntotalargs MAYBE_UNUSED)
       
   997 +{
       
   998 +  cif->nfixedargs = nfixedargs;
       
   999 +#if _CALL_ELF == 2
       
  1000 +  if (cif->abi == FFI_LINUX64)
       
  1001 +    cif->flags |= FLAG_ARG_NEEDS_PSAVE;
       
  1002 +#endif
       
  1003 +  return ffi_prep_cif_machdep_core (cif);
       
  1004 +}
       
  1005 +
       
  1006  extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
       
  1007  			  void (*fn)(void));
       
  1008  extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
       
  1009 @@ -886,28 +1122,39 @@ extern void FFI_HIDDEN ffi_call_LINUX64(
       
  1010  void
       
  1011  ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
       
  1012  {
       
  1013 +  /*
       
  1014 +   * The final SYSV ABI says that structures smaller or equal 8 bytes
       
  1015 +   * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
       
  1016 +   * in memory.
       
  1017 +   *
       
  1018 +   * We bounce-buffer SYSV small struct return values so that sysv.S
       
  1019 +   * can write r3 and r4 to memory without worrying about struct size.
       
  1020 +   *
       
  1021 +   * For ELFv2 ABI, use a bounce buffer for homogeneous structs too,
       
  1022 +   * for similar reasons.
       
  1023 +   */
       
  1024 +  unsigned long smst_buffer[8];
       
  1025    extended_cif ecif;
       
  1026  
       
  1027    ecif.cif = cif;
       
  1028    ecif.avalue = avalue;
       
  1029  
       
  1030 -  /* If the return value is a struct and we don't have a return	*/
       
  1031 -  /* value address then we need to make one		        */
       
  1032 -
       
  1033 -  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
       
  1034 -    {
       
  1035 -      ecif.rvalue = alloca(cif->rtype->size);
       
  1036 -    }
       
  1037 -  else
       
  1038 -    ecif.rvalue = rvalue;
       
  1039 -
       
  1040 +  ecif.rvalue = rvalue;
       
  1041 +  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
       
  1042 +    ecif.rvalue = smst_buffer;
       
  1043 +  /* Ensure that we have a valid struct return value.
       
  1044 +     FIXME: Isn't this just papering over a user problem?  */
       
  1045 +  else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT)
       
  1046 +    ecif.rvalue = alloca (cif->rtype->size);
       
  1047  
       
  1048    switch (cif->abi)
       
  1049      {
       
  1050  #ifndef POWERPC64
       
  1051 +# ifndef __NO_FPRS__
       
  1052      case FFI_SYSV:
       
  1053      case FFI_GCC_SYSV:
       
  1054      case FFI_LINUX:
       
  1055 +# endif
       
  1056      case FFI_LINUX_SOFT_FLOAT:
       
  1057        ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
       
  1058        break;
       
  1059 @@ -920,10 +1167,29 @@ ffi_call(ffi_cif *cif, void (*fn)(void),
       
  1060        FFI_ASSERT (0);
       
  1061        break;
       
  1062      }
       
  1063 +
       
  1064 +  /* Check for a bounce-buffered return value */
       
  1065 +  if (rvalue && ecif.rvalue == smst_buffer)
       
  1066 +    {
       
  1067 +      unsigned int rsize = cif->rtype->size;
       
  1068 +#ifndef __LITTLE_ENDIAN__
       
  1069 +      /* The SYSV ABI returns a structure of up to 4 bytes in size
       
  1070 +	 left-padded in r3.  */
       
  1071 +      if (cif->abi == FFI_SYSV && rsize <= 4)
       
  1072 +	memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize);
       
  1073 +      /* The SYSV ABI returns a structure of up to 8 bytes in size
       
  1074 +	 left-padded in r3/r4, and the ELFv2 ABI similarly returns a
       
  1075 +	 structure of up to 8 bytes in size left-padded in r3.  */
       
  1076 +      else if (rsize <= 8)
       
  1077 +	memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
       
  1078 +      else
       
  1079 +#endif
       
  1080 +	memcpy (rvalue, smst_buffer, rsize);
       
  1081 +    }
       
  1082  }
       
  1083  
       
  1084  
       
  1085 -#ifndef POWERPC64
       
  1086 +#if !defined POWERPC64 || _CALL_ELF == 2
       
  1087  #define MIN_CACHE_LINE_SIZE 8
       
  1088  
       
  1089  static void
       
  1090 @@ -947,16 +1213,38 @@ ffi_prep_closure_loc (ffi_closure *closu
       
  1091  		      void *codeloc)
       
  1092  {
       
  1093  #ifdef POWERPC64
       
  1094 +# if _CALL_ELF == 2
       
  1095 +  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
       
  1096 +
       
  1097 +  if (cif->abi != FFI_LINUX64)
       
  1098 +    return FFI_BAD_ABI;
       
  1099 +
       
  1100 +  tramp[0] = 0xe96c0018;	/* 0:	ld	11,2f-0b(12)	*/
       
  1101 +  tramp[1] = 0xe98c0010;	/*	ld	12,1f-0b(12)	*/
       
  1102 +  tramp[2] = 0x7d8903a6;	/*	mtctr	12		*/
       
  1103 +  tramp[3] = 0x4e800420;	/*	bctr			*/
       
  1104 +				/* 1:	.quad	function_addr	*/
       
  1105 +				/* 2:	.quad	context		*/
       
  1106 +  *(void **) &tramp[4] = (void *) ffi_closure_LINUX64;
       
  1107 +  *(void **) &tramp[6] = codeloc;
       
  1108 +  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
       
  1109 +# else
       
  1110    void **tramp = (void **) &closure->tramp[0];
       
  1111  
       
  1112 -  FFI_ASSERT (cif->abi == FFI_LINUX64);
       
  1113 +  if (cif->abi != FFI_LINUX64)
       
  1114 +    return FFI_BAD_ABI;
       
  1115    /* Copy function address and TOC from ffi_closure_LINUX64.  */
       
  1116    memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
       
  1117    tramp[2] = codeloc;
       
  1118 +# endif
       
  1119  #else
       
  1120    unsigned int *tramp;
       
  1121  
       
  1122 -  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
       
  1123 +  if (! (cif->abi == FFI_GCC_SYSV 
       
  1124 +	 || cif->abi == FFI_SYSV
       
  1125 +	 || cif->abi == FFI_LINUX
       
  1126 +	 || cif->abi == FFI_LINUX_SOFT_FLOAT))
       
  1127 +    return FFI_BAD_ABI;
       
  1128  
       
  1129    tramp = (unsigned int *) &closure->tramp[0];
       
  1130    tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
       
  1131 @@ -1011,32 +1299,38 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1132    void **          avalue;
       
  1133    ffi_type **      arg_types;
       
  1134    long             i, avn;
       
  1135 -  long             nf;   /* number of floating registers already used */
       
  1136 -  long             ng;   /* number of general registers already used */
       
  1137 -  ffi_cif *        cif;
       
  1138 -  double           temp;
       
  1139 -  unsigned         size;
       
  1140 +#ifndef __NO_FPRS__
       
  1141 +  long             nf = 0;   /* number of floating registers already used */
       
  1142 +#endif
       
  1143 +  long             ng = 0;   /* number of general registers already used */
       
  1144 +
       
  1145 +  ffi_cif *cif = closure->cif;
       
  1146 +  unsigned       size     = cif->rtype->size;
       
  1147 +  unsigned short rtypenum = cif->rtype->type;
       
  1148  
       
  1149 -  cif = closure->cif;
       
  1150    avalue = alloca (cif->nargs * sizeof (void *));
       
  1151 -  size = cif->rtype->size;
       
  1152  
       
  1153 -  nf = 0;
       
  1154 -  ng = 0;
       
  1155 +  /* First translate for softfloat/nonlinux */
       
  1156 +  if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
       
  1157 +	if (rtypenum == FFI_TYPE_FLOAT)
       
  1158 +		rtypenum = FFI_TYPE_UINT32;
       
  1159 +	if (rtypenum == FFI_TYPE_DOUBLE)
       
  1160 +		rtypenum = FFI_TYPE_UINT64;
       
  1161 +	if (rtypenum == FFI_TYPE_LONGDOUBLE)
       
  1162 +		rtypenum = FFI_TYPE_UINT128;
       
  1163 +  } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
       
  1164 +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1165 +	if (rtypenum == FFI_TYPE_LONGDOUBLE)
       
  1166 +		rtypenum = FFI_TYPE_STRUCT;
       
  1167 +#endif
       
  1168 +  }
       
  1169 +
       
  1170  
       
  1171    /* Copy the caller's structure return value address so that the closure
       
  1172       returns the data directly to the caller.
       
  1173       For FFI_SYSV the result is passed in r3/r4 if the struct size is less
       
  1174       or equal 8 bytes.  */
       
  1175 -
       
  1176 -  if ((cif->rtype->type == FFI_TYPE_STRUCT
       
  1177 -       && !((cif->abi == FFI_SYSV) && (size <= 8)))
       
  1178 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1179 -      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
       
  1180 -	  && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
       
  1181 -#endif
       
  1182 -      )
       
  1183 -    {
       
  1184 +  if (rtypenum == FFI_TYPE_STRUCT && ((cif->abi != FFI_SYSV) || (size > 8))) {
       
  1185        rvalue = (void *) *pgr;
       
  1186        ng++;
       
  1187        pgr++;
       
  1188 @@ -1047,12 +1341,112 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1189    arg_types = cif->arg_types;
       
  1190  
       
  1191    /* Grab the addresses of the arguments from the stack frame.  */
       
  1192 -  while (i < avn)
       
  1193 -    {
       
  1194 -      switch (arg_types[i]->type)
       
  1195 -	{
       
  1196 +  while (i < avn) {
       
  1197 +      unsigned short typenum = arg_types[i]->type;
       
  1198 +
       
  1199 +      /* We may need to handle some values depending on ABI */
       
  1200 +      if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
       
  1201 +		if (typenum == FFI_TYPE_FLOAT)
       
  1202 +			typenum = FFI_TYPE_UINT32;
       
  1203 +		if (typenum == FFI_TYPE_DOUBLE)
       
  1204 +			typenum = FFI_TYPE_UINT64;
       
  1205 +		if (typenum == FFI_TYPE_LONGDOUBLE)
       
  1206 +			typenum = FFI_TYPE_UINT128;
       
  1207 +      } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
       
  1208 +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1209 +		if (typenum == FFI_TYPE_LONGDOUBLE)
       
  1210 +			typenum = FFI_TYPE_STRUCT;
       
  1211 +#endif
       
  1212 +      }
       
  1213 +
       
  1214 +      switch (typenum) {
       
  1215 +#ifndef __NO_FPRS__
       
  1216 +	case FFI_TYPE_FLOAT:
       
  1217 +	  /* unfortunately float values are stored as doubles
       
  1218 +	   * in the ffi_closure_SYSV code (since we don't check
       
  1219 +	   * the type in that routine).
       
  1220 +	   */
       
  1221 +
       
  1222 +	  /* there are 8 64bit floating point registers */
       
  1223 +
       
  1224 +	  if (nf < 8)
       
  1225 +	    {
       
  1226 +	      double temp = pfr->d;
       
  1227 +	      pfr->f = (float) temp;
       
  1228 +	      avalue[i] = pfr;
       
  1229 +	      nf++;
       
  1230 +	      pfr++;
       
  1231 +	    }
       
  1232 +	  else
       
  1233 +	    {
       
  1234 +	      /* FIXME? here we are really changing the values
       
  1235 +	       * stored in the original calling routines outgoing
       
  1236 +	       * parameter stack.  This is probably a really
       
  1237 +	       * naughty thing to do but...
       
  1238 +	       */
       
  1239 +	      avalue[i] = pst;
       
  1240 +	      pst += 1;
       
  1241 +	    }
       
  1242 +	  break;
       
  1243 +
       
  1244 +	case FFI_TYPE_DOUBLE:
       
  1245 +	  /* On the outgoing stack all values are aligned to 8 */
       
  1246 +	  /* there are 8 64bit floating point registers */
       
  1247 +
       
  1248 +	  if (nf < 8)
       
  1249 +	    {
       
  1250 +	      avalue[i] = pfr;
       
  1251 +	      nf++;
       
  1252 +	      pfr++;
       
  1253 +	    }
       
  1254 +	  else
       
  1255 +	    {
       
  1256 +	      if (((long) pst) & 4)
       
  1257 +		pst++;
       
  1258 +	      avalue[i] = pst;
       
  1259 +	      pst += 2;
       
  1260 +	    }
       
  1261 +	  break;
       
  1262 +
       
  1263 +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1264 +	case FFI_TYPE_LONGDOUBLE:
       
  1265 +	  if (nf < 7)
       
  1266 +	    {
       
  1267 +	      avalue[i] = pfr;
       
  1268 +	      pfr += 2;
       
  1269 +	      nf += 2;
       
  1270 +	    }
       
  1271 +	  else
       
  1272 +	    {
       
  1273 +	      if (((long) pst) & 4)
       
  1274 +		pst++;
       
  1275 +	      avalue[i] = pst;
       
  1276 +	      pst += 4;
       
  1277 +	      nf = 8;
       
  1278 +	    }
       
  1279 +	  break;
       
  1280 +#endif
       
  1281 +#endif /* have FPRS */
       
  1282 +
       
  1283 +	case FFI_TYPE_UINT128:
       
  1284 +		/*
       
  1285 +		 * Test if for the whole long double, 4 gprs are available.
       
  1286 +		 * otherwise the stuff ends up on the stack.
       
  1287 +		 */
       
  1288 +		if (ng < 5) {
       
  1289 +			avalue[i] = pgr;
       
  1290 +			pgr += 4;
       
  1291 +			ng += 4;
       
  1292 +		} else {
       
  1293 +			avalue[i] = pst;
       
  1294 +			pst += 4;
       
  1295 +			ng = 8+4;
       
  1296 +		}
       
  1297 +		break;
       
  1298 +
       
  1299  	case FFI_TYPE_SINT8:
       
  1300  	case FFI_TYPE_UINT8:
       
  1301 +#ifndef __LITTLE_ENDIAN__
       
  1302  	  /* there are 8 gpr registers used to pass values */
       
  1303  	  if (ng < 8)
       
  1304  	    {
       
  1305 @@ -1066,9 +1460,11 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1306  	      pst++;
       
  1307  	    }
       
  1308  	  break;
       
  1309 +#endif
       
  1310  
       
  1311  	case FFI_TYPE_SINT16:
       
  1312  	case FFI_TYPE_UINT16:
       
  1313 +#ifndef __LITTLE_ENDIAN__
       
  1314  	  /* there are 8 gpr registers used to pass values */
       
  1315  	  if (ng < 8)
       
  1316  	    {
       
  1317 @@ -1082,11 +1478,11 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1318  	      pst++;
       
  1319  	    }
       
  1320  	  break;
       
  1321 +#endif
       
  1322  
       
  1323  	case FFI_TYPE_SINT32:
       
  1324  	case FFI_TYPE_UINT32:
       
  1325  	case FFI_TYPE_POINTER:
       
  1326 -	soft_float_closure:
       
  1327  	  /* there are 8 gpr registers used to pass values */
       
  1328  	  if (ng < 8)
       
  1329  	    {
       
  1330 @@ -1102,9 +1498,6 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1331  	  break;
       
  1332  
       
  1333  	case FFI_TYPE_STRUCT:
       
  1334 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1335 -	do_struct:
       
  1336 -#endif
       
  1337  	  /* Structs are passed by reference. The address will appear in a
       
  1338  	     gpr if it is one of the first 8 arguments.  */
       
  1339  	  if (ng < 8)
       
  1340 @@ -1122,7 +1515,6 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1341  
       
  1342  	case FFI_TYPE_SINT64:
       
  1343  	case FFI_TYPE_UINT64:
       
  1344 -	soft_double_closure:
       
  1345  	  /* passing long long ints are complex, they must
       
  1346  	   * be passed in suitable register pairs such as
       
  1347  	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
       
  1348 @@ -1154,99 +1546,8 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1349  	    }
       
  1350  	  break;
       
  1351  
       
  1352 -	case FFI_TYPE_FLOAT:
       
  1353 -	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
       
  1354 -	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
  1355 -	    goto soft_float_closure;
       
  1356 -	  /* unfortunately float values are stored as doubles
       
  1357 -	   * in the ffi_closure_SYSV code (since we don't check
       
  1358 -	   * the type in that routine).
       
  1359 -	   */
       
  1360 -
       
  1361 -	  /* there are 8 64bit floating point registers */
       
  1362 -
       
  1363 -	  if (nf < 8)
       
  1364 -	    {
       
  1365 -	      temp = pfr->d;
       
  1366 -	      pfr->f = (float) temp;
       
  1367 -	      avalue[i] = pfr;
       
  1368 -	      nf++;
       
  1369 -	      pfr++;
       
  1370 -	    }
       
  1371 -	  else
       
  1372 -	    {
       
  1373 -	      /* FIXME? here we are really changing the values
       
  1374 -	       * stored in the original calling routines outgoing
       
  1375 -	       * parameter stack.  This is probably a really
       
  1376 -	       * naughty thing to do but...
       
  1377 -	       */
       
  1378 -	      avalue[i] = pst;
       
  1379 -	      pst += 1;
       
  1380 -	    }
       
  1381 -	  break;
       
  1382 -
       
  1383 -	case FFI_TYPE_DOUBLE:
       
  1384 -	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
       
  1385 -	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
  1386 -	    goto soft_double_closure;
       
  1387 -	  /* On the outgoing stack all values are aligned to 8 */
       
  1388 -	  /* there are 8 64bit floating point registers */
       
  1389 -
       
  1390 -	  if (nf < 8)
       
  1391 -	    {
       
  1392 -	      avalue[i] = pfr;
       
  1393 -	      nf++;
       
  1394 -	      pfr++;
       
  1395 -	    }
       
  1396 -	  else
       
  1397 -	    {
       
  1398 -	      if (((long) pst) & 4)
       
  1399 -		pst++;
       
  1400 -	      avalue[i] = pst;
       
  1401 -	      pst += 2;
       
  1402 -	    }
       
  1403 -	  break;
       
  1404 -
       
  1405 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1406 -	case FFI_TYPE_LONGDOUBLE:
       
  1407 -	  if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
       
  1408 -	    goto do_struct;
       
  1409 -	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
  1410 -	    { /* Test if for the whole long double, 4 gprs are available.
       
  1411 -		 otherwise the stuff ends up on the stack.  */
       
  1412 -	      if (ng < 5)
       
  1413 -		{
       
  1414 -		  avalue[i] = pgr;
       
  1415 -		  pgr += 4;
       
  1416 -		  ng += 4;
       
  1417 -		}
       
  1418 -	      else
       
  1419 -		{
       
  1420 -		  avalue[i] = pst;
       
  1421 -		  pst += 4;
       
  1422 -		  ng = 8;
       
  1423 -		}
       
  1424 -	      break;
       
  1425 -	    }
       
  1426 -	  if (nf < 7)
       
  1427 -	    {
       
  1428 -	      avalue[i] = pfr;
       
  1429 -	      pfr += 2;
       
  1430 -	      nf += 2;
       
  1431 -	    }
       
  1432 -	  else
       
  1433 -	    {
       
  1434 -	      if (((long) pst) & 4)
       
  1435 -		pst++;
       
  1436 -	      avalue[i] = pst;
       
  1437 -	      pst += 4;
       
  1438 -	      nf = 8;
       
  1439 -	    }
       
  1440 -	  break;
       
  1441 -#endif
       
  1442 -
       
  1443  	default:
       
  1444 -	  FFI_ASSERT (0);
       
  1445 +		FFI_ASSERT (0);
       
  1446  	}
       
  1447  
       
  1448        i++;
       
  1449 @@ -1263,39 +1564,9 @@ ffi_closure_helper_SYSV (ffi_closure *cl
       
  1450       already used and we never have a struct with size zero. That is the reason
       
  1451       for the subtraction of 1. See the comment in ffitarget.h about ordering.
       
  1452    */
       
  1453 -  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
       
  1454 -      && size <= 8)
       
  1455 +  if (cif->abi == FFI_SYSV && rtypenum == FFI_TYPE_STRUCT && size <= 8)
       
  1456      return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size;
       
  1457 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1458 -  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
       
  1459 -	   && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
       
  1460 -    return FFI_TYPE_STRUCT;
       
  1461 -#endif
       
  1462 -  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
       
  1463 -     respectivley UINT64.  */
       
  1464 -  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
       
  1465 -    {
       
  1466 -      switch (cif->rtype->type)
       
  1467 -	{
       
  1468 -	case FFI_TYPE_FLOAT:
       
  1469 -	  return FFI_TYPE_UINT32;
       
  1470 -	  break;
       
  1471 -	case FFI_TYPE_DOUBLE:
       
  1472 -	  return FFI_TYPE_UINT64;
       
  1473 -	  break;
       
  1474 -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1475 -	case FFI_TYPE_LONGDOUBLE:
       
  1476 -	  return FFI_TYPE_UINT128;
       
  1477 -	  break;
       
  1478 -#endif
       
  1479 -	default:
       
  1480 -	  return cif->rtype->type;
       
  1481 -	}
       
  1482 -    }
       
  1483 -  else
       
  1484 -    {
       
  1485 -      return cif->rtype->type;
       
  1486 -    }
       
  1487 +  return rtypenum;
       
  1488  }
       
  1489  
       
  1490  int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
       
  1491 @@ -1312,16 +1583,20 @@ ffi_closure_helper_LINUX64 (ffi_closure
       
  1492  
       
  1493    void **avalue;
       
  1494    ffi_type **arg_types;
       
  1495 -  long i, avn;
       
  1496 +  unsigned long i, avn, nfixedargs;
       
  1497    ffi_cif *cif;
       
  1498    ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
       
  1499 +#ifdef __STRUCT_PARM_ALIGN__
       
  1500 +  unsigned long align;
       
  1501 +#endif
       
  1502  
       
  1503    cif = closure->cif;
       
  1504    avalue = alloca (cif->nargs * sizeof (void *));
       
  1505  
       
  1506 -  /* Copy the caller's structure return value address so that the closure
       
  1507 -     returns the data directly to the caller.  */
       
  1508 -  if (cif->rtype->type == FFI_TYPE_STRUCT)
       
  1509 +  /* Copy the caller's structure return value address so that the
       
  1510 +     closure returns the data directly to the caller.  */
       
  1511 +  if (cif->rtype->type == FFI_TYPE_STRUCT
       
  1512 +      && (cif->flags & FLAG_RETURNS_SMST) == 0)
       
  1513      {
       
  1514        rvalue = (void *) *pst;
       
  1515        pst++;
       
  1516 @@ -1329,30 +1604,39 @@ ffi_closure_helper_LINUX64 (ffi_closure
       
  1517  
       
  1518    i = 0;
       
  1519    avn = cif->nargs;
       
  1520 +  nfixedargs = cif->nfixedargs;
       
  1521    arg_types = cif->arg_types;
       
  1522  
       
  1523    /* Grab the addresses of the arguments from the stack frame.  */
       
  1524    while (i < avn)
       
  1525      {
       
  1526 +      unsigned int elt, elnum;
       
  1527 +
       
  1528        switch (arg_types[i]->type)
       
  1529  	{
       
  1530  	case FFI_TYPE_SINT8:
       
  1531  	case FFI_TYPE_UINT8:
       
  1532 +#ifndef __LITTLE_ENDIAN__
       
  1533  	  avalue[i] = (char *) pst + 7;
       
  1534  	  pst++;
       
  1535  	  break;
       
  1536 +#endif
       
  1537  
       
  1538  	case FFI_TYPE_SINT16:
       
  1539  	case FFI_TYPE_UINT16:
       
  1540 +#ifndef __LITTLE_ENDIAN__
       
  1541  	  avalue[i] = (char *) pst + 6;
       
  1542  	  pst++;
       
  1543  	  break;
       
  1544 +#endif
       
  1545  
       
  1546  	case FFI_TYPE_SINT32:
       
  1547  	case FFI_TYPE_UINT32:
       
  1548 +#ifndef __LITTLE_ENDIAN__
       
  1549  	  avalue[i] = (char *) pst + 4;
       
  1550  	  pst++;
       
  1551  	  break;
       
  1552 +#endif
       
  1553  
       
  1554  	case FFI_TYPE_SINT64:
       
  1555  	case FFI_TYPE_UINT64:
       
  1556 @@ -1362,12 +1646,82 @@ ffi_closure_helper_LINUX64 (ffi_closure
       
  1557  	  break;
       
  1558  
       
  1559  	case FFI_TYPE_STRUCT:
       
  1560 -	  /* Structures with size less than eight bytes are passed
       
  1561 -	     left-padded.  */
       
  1562 -	  if (arg_types[i]->size < 8)
       
  1563 -	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
       
  1564 +#ifdef __STRUCT_PARM_ALIGN__
       
  1565 +	  align = arg_types[i]->alignment;
       
  1566 +	  if (align > __STRUCT_PARM_ALIGN__)
       
  1567 +	    align = __STRUCT_PARM_ALIGN__;
       
  1568 +	  if (align > 1)
       
  1569 +	    pst = (unsigned long *) ALIGN ((size_t) pst, align);
       
  1570 +#endif
       
  1571 +	  elt = 0;
       
  1572 +#if _CALL_ELF == 2
       
  1573 +	  elt = discover_homogeneous_aggregate (arg_types[i], &elnum);
       
  1574 +#endif
       
  1575 +	  if (elt)
       
  1576 +	    {
       
  1577 +	      union {
       
  1578 +		void *v;
       
  1579 +		unsigned long *ul;
       
  1580 +		float *f;
       
  1581 +		double *d;
       
  1582 +		size_t p;
       
  1583 +	      } to, from;
       
  1584 +
       
  1585 +	      /* Repackage the aggregate from its parts.  The
       
  1586 +		 aggregate size is not greater than the space taken by
       
  1587 +		 the registers so store back to the register/parameter
       
  1588 +		 save arrays.  */
       
  1589 +	      if (pfr + elnum <= end_pfr)
       
  1590 +		to.v = pfr;
       
  1591 +	      else
       
  1592 +		to.v = pst;
       
  1593 +
       
  1594 +	      avalue[i] = to.v;
       
  1595 +	      from.ul = pst;
       
  1596 +	      if (elt == FFI_TYPE_FLOAT)
       
  1597 +		{
       
  1598 +		  do
       
  1599 +		    {
       
  1600 +		      if (pfr < end_pfr && i < nfixedargs)
       
  1601 +			{
       
  1602 +			  *to.f = (float) pfr->d;
       
  1603 +			  pfr++;
       
  1604 +			}
       
  1605 +		      else
       
  1606 +			*to.f = *from.f;
       
  1607 +		      to.f++;
       
  1608 +		      from.f++;
       
  1609 +		    }
       
  1610 +		  while (--elnum != 0);
       
  1611 +		}
       
  1612 +	      else
       
  1613 +		{
       
  1614 +		  do
       
  1615 +		    {
       
  1616 +		      if (pfr < end_pfr && i < nfixedargs)
       
  1617 +			{
       
  1618 +			  *to.d = pfr->d;
       
  1619 +			  pfr++;
       
  1620 +			}
       
  1621 +		      else
       
  1622 +			*to.d = *from.d;
       
  1623 +		      to.d++;
       
  1624 +		      from.d++;
       
  1625 +		    }
       
  1626 +		  while (--elnum != 0);
       
  1627 +		}
       
  1628 +	    }
       
  1629  	  else
       
  1630 -	    avalue[i] = pst;
       
  1631 +	    {
       
  1632 +#ifndef __LITTLE_ENDIAN__
       
  1633 +	      /* Structures with size less than eight bytes are passed
       
  1634 +		 left-padded.  */
       
  1635 +	      if (arg_types[i]->size < 8)
       
  1636 +		avalue[i] = (char *) pst + 8 - arg_types[i]->size;
       
  1637 +	      else
       
  1638 +#endif
       
  1639 +		avalue[i] = pst;
       
  1640 +	    }
       
  1641  	  pst += (arg_types[i]->size + 7) / 8;
       
  1642  	  break;
       
  1643  
       
  1644 @@ -1379,7 +1733,7 @@ ffi_closure_helper_LINUX64 (ffi_closure
       
  1645  
       
  1646  	  /* there are 13 64bit floating point registers */
       
  1647  
       
  1648 -	  if (pfr < end_pfr)
       
  1649 +	  if (pfr < end_pfr && i < nfixedargs)
       
  1650  	    {
       
  1651  	      double temp = pfr->d;
       
  1652  	      pfr->f = (float) temp;
       
  1653 @@ -1395,7 +1749,7 @@ ffi_closure_helper_LINUX64 (ffi_closure
       
  1654  	  /* On the outgoing stack all values are aligned to 8 */
       
  1655  	  /* there are 13 64bit floating point registers */
       
  1656  
       
  1657 -	  if (pfr < end_pfr)
       
  1658 +	  if (pfr < end_pfr && i < nfixedargs)
       
  1659  	    {
       
  1660  	      avalue[i] = pfr;
       
  1661  	      pfr++;
       
  1662 @@ -1407,14 +1761,14 @@ ffi_closure_helper_LINUX64 (ffi_closure
       
  1663  
       
  1664  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1665  	case FFI_TYPE_LONGDOUBLE:
       
  1666 -	  if (pfr + 1 < end_pfr)
       
  1667 +	  if (pfr + 1 < end_pfr && i + 1 < nfixedargs)
       
  1668  	    {
       
  1669  	      avalue[i] = pfr;
       
  1670  	      pfr += 2;
       
  1671  	    }
       
  1672  	  else
       
  1673  	    {
       
  1674 -	      if (pfr < end_pfr)
       
  1675 +	      if (pfr < end_pfr && i < nfixedargs)
       
  1676  		{
       
  1677  		  /* Passed partly in f13 and partly on the stack.
       
  1678  		     Move it all to the stack.  */
       
  1679 @@ -1438,5 +1792,14 @@ ffi_closure_helper_LINUX64 (ffi_closure
       
  1680    (closure->fun) (cif, rvalue, avalue, closure->user_data);
       
  1681  
       
  1682    /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
       
  1683 +  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
       
  1684 +    {
       
  1685 +      if ((cif->flags & FLAG_RETURNS_FP) == 0)
       
  1686 +	return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1;
       
  1687 +      else if ((cif->flags & FLAG_RETURNS_64BITS) != 0)
       
  1688 +	return FFI_V2_TYPE_DOUBLE_HOMOG;
       
  1689 +      else
       
  1690 +	return FFI_V2_TYPE_FLOAT_HOMOG;
       
  1691 +    }
       
  1692    return cif->rtype->type;
       
  1693  }
       
  1694 --- mozilla/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c	2013-10-24 09:56:51.846587814 +0200
       
  1695 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/ffi_darwin.c	2013-11-29 17:23:26.000000000 +0100
       
  1696 @@ -3,7 +3,7 @@
       
  1697  
       
  1698     Copyright (C) 1998 Geoffrey Keating
       
  1699     Copyright (C) 2001 John Hornkvist
       
  1700 -   Copyright (C) 2002, 2006, 2007, 2009 Free Software Foundation, Inc.
       
  1701 +   Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
       
  1702  
       
  1703     FFI support for Darwin and AIX.
       
  1704     
       
  1705 @@ -35,11 +35,17 @@
       
  1706  extern void ffi_closure_ASM (void);
       
  1707  
       
  1708  enum {
       
  1709 -  /* The assembly depends on these exact flags.  */
       
  1710 -  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7  */
       
  1711 -  FLAG_RETURNS_FP       = 1 << (31-29),
       
  1712 -  FLAG_RETURNS_64BITS   = 1 << (31-28),
       
  1713 -  FLAG_RETURNS_128BITS  = 1 << (31-31),
       
  1714 +  /* The assembly depends on these exact flags.  
       
  1715 +     For Darwin64 (when FLAG_RETURNS_STRUCT is set):
       
  1716 +       FLAG_RETURNS_FP indicates that the structure embeds FP data.
       
  1717 +       FLAG_RETURNS_128BITS signals a special struct size that is not
       
  1718 +       expanded for float content.  */
       
  1719 +  FLAG_RETURNS_128BITS	= 1 << (31-31), /* These go in cr7  */
       
  1720 +  FLAG_RETURNS_NOTHING	= 1 << (31-30),
       
  1721 +  FLAG_RETURNS_FP	= 1 << (31-29),
       
  1722 +  FLAG_RETURNS_64BITS	= 1 << (31-28),
       
  1723 +
       
  1724 +  FLAG_RETURNS_STRUCT	= 1 << (31-27), /* This goes in cr6  */
       
  1725  
       
  1726    FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
       
  1727    FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
       
  1728 @@ -50,43 +56,61 @@ enum {
       
  1729  /* About the DARWIN ABI.  */
       
  1730  enum {
       
  1731    NUM_GPR_ARG_REGISTERS = 8,
       
  1732 -  NUM_FPR_ARG_REGISTERS = 13
       
  1733 +  NUM_FPR_ARG_REGISTERS = 13,
       
  1734 +  LINKAGE_AREA_GPRS = 6
       
  1735  };
       
  1736 -enum { ASM_NEEDS_REGISTERS = 4 };
       
  1737 +
       
  1738 +enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */
       
  1739  
       
  1740  /* ffi_prep_args is called by the assembly routine once stack space
       
  1741     has been allocated for the function's arguments.
       
  1742 +   
       
  1743 +   m32/m64
       
  1744  
       
  1745     The stack layout we want looks like this:
       
  1746  
       
  1747     |   Return address from ffi_call_DARWIN      |	higher addresses
       
  1748     |--------------------------------------------|
       
  1749 -   |   Previous backchain pointer	4	|	stack pointer here
       
  1750 +   |   Previous backchain pointer	4/8	|	stack pointer here
       
  1751     |--------------------------------------------|<+ <<<	on entry to
       
  1752 -   |   Saved r28-r31			4*4	| |	ffi_call_DARWIN
       
  1753 +   |   ASM_NEEDS_REGISTERS=r28-r31   4*(4/8)	| |	ffi_call_DARWIN
       
  1754     |--------------------------------------------| |
       
  1755 -   |   Parameters             (at least 8*4=32) | |
       
  1756 +   |   When we have any FP activity... the	| |
       
  1757 +   |   FPRs occupy NUM_FPR_ARG_REGISTERS slots	| |
       
  1758 +   |   here fp13 .. fp1 from high to low addr.	| |
       
  1759 +   ~						~ ~
       
  1760 +   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
       
  1761     |--------------------------------------------| |
       
  1762 -   |   Space for GPR2                   4       | |
       
  1763 +   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
       
  1764     |--------------------------------------------| |	stack	|
       
  1765 -   |   Reserved                       2*4       | |	grows	|
       
  1766 +   |   Reserved                       2*4/8	| |	grows	|
       
  1767     |--------------------------------------------| |	down	V
       
  1768 -   |   Space for callee's LR		4	| |
       
  1769 +   |   Space for callee's LR		4/8	| |
       
  1770     |--------------------------------------------| |	lower addresses
       
  1771 -   |   Saved CR                         4       | |
       
  1772 +   |   Saved CR [low word for m64]      4/8	| |
       
  1773     |--------------------------------------------| |     stack pointer here
       
  1774 -   |   Current backchain pointer	4	|-/	during
       
  1775 +   |   Current backchain pointer	4/8	|-/	during
       
  1776     |--------------------------------------------|   <<<	ffi_call_DARWIN
       
  1777  
       
  1778     */
       
  1779  
       
  1780 +#if defined(POWERPC_DARWIN64)
       
  1781 +static void
       
  1782 +darwin64_pass_struct_by_value 
       
  1783 +  (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **);
       
  1784 +#endif
       
  1785 +
       
  1786 +/* This depends on GPR_SIZE = sizeof (unsigned long) */
       
  1787 +
       
  1788  void
       
  1789  ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
       
  1790  {
       
  1791    const unsigned bytes = ecif->cif->bytes;
       
  1792    const unsigned flags = ecif->cif->flags;
       
  1793    const unsigned nargs = ecif->cif->nargs;
       
  1794 +#if !defined(POWERPC_DARWIN64) 
       
  1795    const ffi_abi abi = ecif->cif->abi;
       
  1796 +#endif
       
  1797  
       
  1798    /* 'stacktop' points at the previous backchain pointer.  */
       
  1799    unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
       
  1800 @@ -94,18 +118,19 @@ ffi_prep_args (extended_cif *ecif, unsig
       
  1801    /* 'fpr_base' points at the space for fpr1, and grows upwards as
       
  1802       we use FPR registers.  */
       
  1803    double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
       
  1804 -  int fparg_count = 0;
       
  1805 -
       
  1806 +  int gp_count = 0, fparg_count = 0;
       
  1807  
       
  1808    /* 'next_arg' grows up as we put parameters in it.  */
       
  1809 -  unsigned long *next_arg = stack + 6; /* 6 reserved positions.  */
       
  1810 +  unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions.  */
       
  1811  
       
  1812    int i;
       
  1813    double double_tmp;
       
  1814    void **p_argv = ecif->avalue;
       
  1815    unsigned long gprvalue;
       
  1816    ffi_type** ptr = ecif->cif->arg_types;
       
  1817 +#if !defined(POWERPC_DARWIN64) 
       
  1818    char *dest_cpy;
       
  1819 +#endif
       
  1820    unsigned size_al = 0;
       
  1821  
       
  1822    /* Check that everything starts aligned properly.  */
       
  1823 @@ -130,25 +155,30 @@ ffi_prep_args (extended_cif *ecif, unsig
       
  1824  	   the size of the floating-point parameter are skipped.  */
       
  1825  	case FFI_TYPE_FLOAT:
       
  1826  	  double_tmp = *(float *) *p_argv;
       
  1827 -	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
       
  1828 -	    *(double *)next_arg = double_tmp;
       
  1829 -	  else
       
  1830 +	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
       
  1831  	    *fpr_base++ = double_tmp;
       
  1832 +#if defined(POWERPC_DARWIN)
       
  1833 +	  *(float *)next_arg = *(float *) *p_argv;
       
  1834 +#else
       
  1835 +	  *(double *)next_arg = double_tmp;
       
  1836 +#endif
       
  1837  	  next_arg++;
       
  1838 +	  gp_count++;
       
  1839  	  fparg_count++;
       
  1840  	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
       
  1841  	  break;
       
  1842  
       
  1843  	case FFI_TYPE_DOUBLE:
       
  1844  	  double_tmp = *(double *) *p_argv;
       
  1845 -	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
       
  1846 -	    *(double *)next_arg = double_tmp;
       
  1847 -	  else
       
  1848 +	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
       
  1849  	    *fpr_base++ = double_tmp;
       
  1850 +	  *(double *)next_arg = double_tmp;
       
  1851  #ifdef POWERPC64
       
  1852  	  next_arg++;
       
  1853 +	  gp_count++;
       
  1854  #else
       
  1855  	  next_arg += 2;
       
  1856 +	  gp_count += 2;
       
  1857  #endif
       
  1858  	  fparg_count++;
       
  1859  	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
       
  1860 @@ -157,30 +187,41 @@ ffi_prep_args (extended_cif *ecif, unsig
       
  1861  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  1862  
       
  1863  	case FFI_TYPE_LONGDOUBLE:
       
  1864 -#ifdef POWERPC64
       
  1865 +#  if defined(POWERPC64) && !defined(POWERPC_DARWIN64)
       
  1866 +	  /* ??? This will exceed the regs count when the value starts at fp13
       
  1867 +	     and it will not put the extra bit on the stack.  */
       
  1868  	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
       
  1869  	    *(long double *) fpr_base++ = *(long double *) *p_argv;
       
  1870  	  else
       
  1871  	    *(long double *) next_arg = *(long double *) *p_argv;
       
  1872  	  next_arg += 2;
       
  1873  	  fparg_count += 2;
       
  1874 -#else
       
  1875 +#  else
       
  1876  	  double_tmp = ((double *) *p_argv)[0];
       
  1877  	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
       
  1878  	    *fpr_base++ = double_tmp;
       
  1879 -	  else
       
  1880 -	    *(double *) next_arg = double_tmp;
       
  1881 +	  *(double *) next_arg = double_tmp;
       
  1882 +#    if defined(POWERPC_DARWIN64)
       
  1883 +	  next_arg++;
       
  1884 +	  gp_count++;
       
  1885 +#    else
       
  1886  	  next_arg += 2;
       
  1887 +	  gp_count += 2;
       
  1888 +#    endif
       
  1889  	  fparg_count++;
       
  1890 -
       
  1891  	  double_tmp = ((double *) *p_argv)[1];
       
  1892  	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
       
  1893  	    *fpr_base++ = double_tmp;
       
  1894 -	  else
       
  1895 -	    *(double *) next_arg = double_tmp;
       
  1896 +	  *(double *) next_arg = double_tmp;
       
  1897 +#    if defined(POWERPC_DARWIN64)
       
  1898 +	  next_arg++;
       
  1899 +	  gp_count++;
       
  1900 +#    else
       
  1901  	  next_arg += 2;
       
  1902 +	  gp_count += 2;
       
  1903 +#    endif
       
  1904  	  fparg_count++;
       
  1905 -#endif
       
  1906 +#  endif
       
  1907  	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
       
  1908  	  break;
       
  1909  #endif
       
  1910 @@ -192,6 +233,7 @@ ffi_prep_args (extended_cif *ecif, unsig
       
  1911  #else
       
  1912  	  *(long long *) next_arg = *(long long *) *p_argv;
       
  1913  	  next_arg += 2;
       
  1914 +	  gp_count += 2;
       
  1915  #endif
       
  1916  	  break;
       
  1917  	case FFI_TYPE_POINTER:
       
  1918 @@ -211,32 +253,35 @@ ffi_prep_args (extended_cif *ecif, unsig
       
  1919  	  goto putgpr;
       
  1920  
       
  1921  	case FFI_TYPE_STRUCT:
       
  1922 -#ifdef POWERPC64
       
  1923 -	  dest_cpy = (char *) next_arg;
       
  1924  	  size_al = (*ptr)->size;
       
  1925 -	  if ((*ptr)->elements[0]->type == 3)
       
  1926 +#if defined(POWERPC_DARWIN64)
       
  1927 +	  next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment);
       
  1928 +	  darwin64_pass_struct_by_value (*ptr, (char *) *p_argv, 
       
  1929 +					 (unsigned) size_al,
       
  1930 +					 (unsigned int *) &fparg_count,
       
  1931 +					 &fpr_base, &next_arg);
       
  1932 +#else
       
  1933 +	  dest_cpy = (char *) next_arg;
       
  1934 +
       
  1935 +	  /* If the first member of the struct is a double, then include enough
       
  1936 +	     padding in the struct size to align it to double-word.  */
       
  1937 +	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
       
  1938  	    size_al = ALIGN((*ptr)->size, 8);
       
  1939 -	  if (size_al < 3 && abi == FFI_DARWIN)
       
  1940 -	    dest_cpy += 4 - size_al;
       
  1941  
       
  1942 +#  if defined(POWERPC64) 
       
  1943 +	  FFI_ASSERT (abi != FFI_DARWIN);
       
  1944  	  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
       
  1945  	  next_arg += (size_al + 7) / 8;
       
  1946 -#else
       
  1947 -	  dest_cpy = (char *) next_arg;
       
  1948 -
       
  1949 +#  else
       
  1950  	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
       
  1951  	     SI 4 bytes) are aligned as if they were those modes.
       
  1952  	     Structures with 3 byte in size are padded upwards.  */
       
  1953 -	  size_al = (*ptr)->size;
       
  1954 -	  /* If the first member of the struct is a double, then align
       
  1955 -	     the struct to double-word.  */
       
  1956 -	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
       
  1957 -	    size_al = ALIGN((*ptr)->size, 8);
       
  1958  	  if (size_al < 3 && abi == FFI_DARWIN)
       
  1959  	    dest_cpy += 4 - size_al;
       
  1960  
       
  1961  	  memcpy((char *) dest_cpy, (char *) *p_argv, size_al);
       
  1962  	  next_arg += (size_al + 3) / 4;
       
  1963 +#  endif
       
  1964  #endif
       
  1965  	  break;
       
  1966  
       
  1967 @@ -249,6 +294,7 @@ ffi_prep_args (extended_cif *ecif, unsig
       
  1968  	  gprvalue = *(unsigned int *) *p_argv;
       
  1969  	putgpr:
       
  1970  	  *next_arg++ = gprvalue;
       
  1971 +	  gp_count++;
       
  1972  	  break;
       
  1973  	default:
       
  1974  	  break;
       
  1975 @@ -262,8 +308,269 @@ ffi_prep_args (extended_cif *ecif, unsig
       
  1976    //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
       
  1977  }
       
  1978  
       
  1979 +#if defined(POWERPC_DARWIN64)
       
  1980 +
       
  1981 +/* See if we can put some of the struct into fprs.
       
  1982 +   This should not be called for structures of size 16 bytes, since these are not
       
  1983 +   broken out this way.  */
       
  1984 +static void
       
  1985 +darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr)
       
  1986 +{
       
  1987 +  int i;
       
  1988 +
       
  1989 +  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
       
  1990 +
       
  1991 +  for (i = 0; s->elements[i] != NULL; i++)
       
  1992 +    {
       
  1993 +      ffi_type *p = s->elements[i];
       
  1994 +      switch (p->type)
       
  1995 +	{
       
  1996 +	  case FFI_TYPE_STRUCT:
       
  1997 +	    darwin64_scan_struct_for_floats (p, nfpr);
       
  1998 +	    break;
       
  1999 +	  case FFI_TYPE_LONGDOUBLE:
       
  2000 +	    (*nfpr) += 2;
       
  2001 +	    break;
       
  2002 +	  case FFI_TYPE_DOUBLE:
       
  2003 +	  case FFI_TYPE_FLOAT:
       
  2004 +	    (*nfpr) += 1;
       
  2005 +	    break;
       
  2006 +	  default:
       
  2007 +	    break;    
       
  2008 +	}
       
  2009 +    }
       
  2010 +}
       
  2011 +
       
  2012 +static int
       
  2013 +darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr)
       
  2014 +{
       
  2015 +  unsigned struct_offset=0, i;
       
  2016 +
       
  2017 +  for (i = 0; s->elements[i] != NULL; i++)
       
  2018 +    {
       
  2019 +      char *item_base;
       
  2020 +      ffi_type *p = s->elements[i];
       
  2021 +      /* Find the start of this item (0 for the first one).  */
       
  2022 +      if (i > 0)
       
  2023 +        struct_offset = ALIGN(struct_offset, p->alignment);
       
  2024 +
       
  2025 +      item_base = src + struct_offset;
       
  2026 +
       
  2027 +      switch (p->type)
       
  2028 +	{
       
  2029 +	  case FFI_TYPE_STRUCT:
       
  2030 +	    if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))
       
  2031 +	      return 1;
       
  2032 +	    break;
       
  2033 +	  case FFI_TYPE_LONGDOUBLE:
       
  2034 +	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
       
  2035 +	      return 1;
       
  2036 +	    (*nfpr) += 1;
       
  2037 +	    item_base += 8;
       
  2038 +	  /* FALL THROUGH */
       
  2039 +	  case FFI_TYPE_DOUBLE:
       
  2040 +	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
       
  2041 +	      return 1;
       
  2042 +	    (*nfpr) += 1;
       
  2043 +	    break;
       
  2044 +	  case FFI_TYPE_FLOAT:
       
  2045 +	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
       
  2046 +	      return 1;
       
  2047 +	    (*nfpr) += 1;
       
  2048 +	    break;
       
  2049 +	  default:
       
  2050 +	    /* If we try and place any item, that is non-float, once we've
       
  2051 +	       exceeded the 8 GPR mark, then we can't fit the struct.  */
       
  2052 +	    if ((unsigned long)item_base >= 8*8) 
       
  2053 +	      return 1;
       
  2054 +	    break;    
       
  2055 +	}
       
  2056 +      /* now count the size of what we just used.  */
       
  2057 +      struct_offset += p->size;
       
  2058 +    }
       
  2059 +  return 0;
       
  2060 +}
       
  2061 +
       
  2062 +/* Can this struct be returned by value?  */
       
  2063 +int 
       
  2064 +darwin64_struct_ret_by_value_p (ffi_type *s)
       
  2065 +{
       
  2066 +  unsigned nfp = 0;
       
  2067 +
       
  2068 +  FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT);
       
  2069 +  
       
  2070 +  /* The largest structure we can return is 8long + 13 doubles.  */
       
  2071 +  if (s->size > 168)
       
  2072 +    return 0;
       
  2073 +  
       
  2074 +  /* We can't pass more than 13 floats.  */
       
  2075 +  darwin64_scan_struct_for_floats (s, &nfp);
       
  2076 +  if (nfp > 13)
       
  2077 +    return 0;
       
  2078 +  
       
  2079 +  /* If there are not too many floats, and the struct is
       
  2080 +     small enough to accommodate in the GPRs, then it must be OK.  */
       
  2081 +  if (s->size <= 64)
       
  2082 +    return 1;
       
  2083 +  
       
  2084 +  /* Well, we have to look harder.  */
       
  2085 +  nfp = 0;
       
  2086 +  if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp))
       
  2087 +    return 0;
       
  2088 +  
       
  2089 +  return 1;
       
  2090 +}
       
  2091 +
       
  2092 +void
       
  2093 +darwin64_pass_struct_floats (ffi_type *s, char *src, 
       
  2094 +			     unsigned *nfpr, double **fprs)
       
  2095 +{
       
  2096 +  int i;
       
  2097 +  double *fpr_base = *fprs;
       
  2098 +  unsigned struct_offset = 0;
       
  2099 +
       
  2100 +  /* We don't assume anything about the alignment of the source.  */
       
  2101 +  for (i = 0; s->elements[i] != NULL; i++)
       
  2102 +    {
       
  2103 +      char *item_base;
       
  2104 +      ffi_type *p = s->elements[i];
       
  2105 +      /* Find the start of this item (0 for the first one).  */
       
  2106 +      if (i > 0)
       
  2107 +        struct_offset = ALIGN(struct_offset, p->alignment);
       
  2108 +      item_base = src + struct_offset;
       
  2109 +
       
  2110 +      switch (p->type)
       
  2111 +	{
       
  2112 +	  case FFI_TYPE_STRUCT:
       
  2113 +	    darwin64_pass_struct_floats (p, item_base, nfpr,
       
  2114 +					   &fpr_base);
       
  2115 +	    break;
       
  2116 +	  case FFI_TYPE_LONGDOUBLE:
       
  2117 +	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
       
  2118 +	      *fpr_base++ = *(double *)item_base;
       
  2119 +	    (*nfpr) += 1;
       
  2120 +	    item_base += 8;
       
  2121 +	  /* FALL THROUGH */
       
  2122 +	  case FFI_TYPE_DOUBLE:
       
  2123 +	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
       
  2124 +	      *fpr_base++ = *(double *)item_base;
       
  2125 +	    (*nfpr) += 1;
       
  2126 +	    break;
       
  2127 +	  case FFI_TYPE_FLOAT:
       
  2128 +	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
       
  2129 +	      *fpr_base++ = (double) *(float *)item_base;
       
  2130 +	    (*nfpr) += 1;
       
  2131 +	    break;
       
  2132 +	  default:
       
  2133 +	    break;    
       
  2134 +	}
       
  2135 +      /* now count the size of what we just used.  */
       
  2136 +      struct_offset += p->size;
       
  2137 +    }
       
  2138 +  /* Update the scores.  */
       
  2139 +  *fprs = fpr_base;
       
  2140 +}
       
  2141 +
       
  2142 +/* Darwin64 special rules.
       
  2143 +   Break out a struct into params and float registers.  */
       
  2144 +static void
       
  2145 +darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size,
       
  2146 +			       unsigned *nfpr, double **fprs, unsigned long **arg)
       
  2147 +{
       
  2148 +  unsigned long *next_arg = *arg;
       
  2149 +  char *dest_cpy = (char *)next_arg;
       
  2150 +
       
  2151 +  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
       
  2152 +
       
  2153 +  if (!size)
       
  2154 +    return;
       
  2155 +
       
  2156 +  /* First... special cases.  */
       
  2157 +  if (size < 3
       
  2158 +      || (size == 4 
       
  2159 +	  && s->elements[0] 
       
  2160 +	  && s->elements[0]->type != FFI_TYPE_FLOAT))
       
  2161 +    {
       
  2162 +      /* Must be at least one GPR, padding is unspecified in value, 
       
  2163 +	 let's make it zero.  */
       
  2164 +      *next_arg = 0UL; 
       
  2165 +      dest_cpy += 8 - size;
       
  2166 +      memcpy ((char *) dest_cpy, src, size);
       
  2167 +      next_arg++;
       
  2168 +    }
       
  2169 +  else if (size == 16)
       
  2170 +    {
       
  2171 +      memcpy ((char *) dest_cpy, src, size);
       
  2172 +      next_arg += 2;
       
  2173 +    }
       
  2174 +  else
       
  2175 +    {
       
  2176 +      /* now the general case, we consider embedded floats.  */
       
  2177 +      memcpy ((char *) dest_cpy, src, size);
       
  2178 +      darwin64_pass_struct_floats (s, src, nfpr, fprs);
       
  2179 +      next_arg += (size+7)/8;
       
  2180 +    }
       
  2181 +    
       
  2182 +  *arg = next_arg;
       
  2183 +}
       
  2184 +
       
  2185 +double *
       
  2186 +darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf)
       
  2187 +{
       
  2188 +  int i;
       
  2189 +  unsigned struct_offset = 0;
       
  2190 +
       
  2191 +  /* We don't assume anything about the alignment of the source.  */
       
  2192 +  for (i = 0; s->elements[i] != NULL; i++)
       
  2193 +    {
       
  2194 +      char *item_base;
       
  2195 +      ffi_type *p = s->elements[i];
       
  2196 +      /* Find the start of this item (0 for the first one).  */
       
  2197 +      if (i > 0)
       
  2198 +        struct_offset = ALIGN(struct_offset, p->alignment);
       
  2199 +      item_base = dest + struct_offset;
       
  2200 +
       
  2201 +      switch (p->type)
       
  2202 +	{
       
  2203 +	  case FFI_TYPE_STRUCT:
       
  2204 +	    fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);
       
  2205 +	    break;
       
  2206 +	  case FFI_TYPE_LONGDOUBLE:
       
  2207 +	    if (*nf < NUM_FPR_ARG_REGISTERS)
       
  2208 +	      {
       
  2209 +		*(double *)item_base = *fprs++ ;
       
  2210 +		(*nf) += 1;
       
  2211 +	      }
       
  2212 +	    item_base += 8;
       
  2213 +	  /* FALL THROUGH */
       
  2214 +	  case FFI_TYPE_DOUBLE:
       
  2215 +	    if (*nf < NUM_FPR_ARG_REGISTERS)
       
  2216 +	      {
       
  2217 +		*(double *)item_base = *fprs++ ;
       
  2218 +		(*nf) += 1;
       
  2219 +	      }
       
  2220 +	    break;
       
  2221 +	  case FFI_TYPE_FLOAT:
       
  2222 +	    if (*nf < NUM_FPR_ARG_REGISTERS)
       
  2223 +	      {
       
  2224 +		*(float *)item_base = (float) *fprs++ ;
       
  2225 +		(*nf) += 1;
       
  2226 +	      }
       
  2227 +	    break;
       
  2228 +	  default:
       
  2229 +	    break;    
       
  2230 +	}
       
  2231 +      /* now count the size of what we just used.  */
       
  2232 +      struct_offset += p->size;
       
  2233 +    }
       
  2234 +  return fprs;
       
  2235 +}
       
  2236 +
       
  2237 +#endif
       
  2238 +
       
  2239  /* Adjust the size of S to be correct for Darwin.
       
  2240 -   On Darwin, the first field of a structure has natural alignment.  */
       
  2241 +   On Darwin m32, the first field of a structure has natural alignment.  
       
  2242 +   On Darwin m64, all fields have natural alignment.  */
       
  2243  
       
  2244  static void
       
  2245  darwin_adjust_aggregate_sizes (ffi_type *s)
       
  2246 @@ -280,22 +587,29 @@ darwin_adjust_aggregate_sizes (ffi_type
       
  2247        int align;
       
  2248        
       
  2249        p = s->elements[i];
       
  2250 -      darwin_adjust_aggregate_sizes (p);
       
  2251 -      if (i == 0
       
  2252 -	  && (p->type == FFI_TYPE_UINT64
       
  2253 -	      || p->type == FFI_TYPE_SINT64
       
  2254 -	      || p->type == FFI_TYPE_DOUBLE
       
  2255 -	      || p->alignment == 8))
       
  2256 -	align = 8;
       
  2257 +      if (p->type == FFI_TYPE_STRUCT)
       
  2258 +	darwin_adjust_aggregate_sizes (p);
       
  2259 +#if defined(POWERPC_DARWIN64)
       
  2260 +      /* Natural alignment for all items.  */
       
  2261 +      align = p->alignment;
       
  2262 +#else
       
  2263 +      /* Natrual alignment for the first item... */
       
  2264 +      if (i == 0)
       
  2265 +	align = p->alignment;
       
  2266        else if (p->alignment == 16 || p->alignment < 4)
       
  2267 +	/* .. subsequent items with vector or align < 4 have natural align.  */
       
  2268  	align = p->alignment;
       
  2269        else
       
  2270 +	/* .. or align is 4.  */
       
  2271  	align = 4;
       
  2272 +#endif
       
  2273 +      /* Pad, if necessary, before adding the current item.  */
       
  2274        s->size = ALIGN(s->size, align) + p->size;
       
  2275      }
       
  2276    
       
  2277    s->size = ALIGN(s->size, s->alignment);
       
  2278    
       
  2279 +  /* This should not be necessary on m64, but harmless.  */
       
  2280    if (s->elements[0]->type == FFI_TYPE_UINT64
       
  2281        || s->elements[0]->type == FFI_TYPE_SINT64
       
  2282        || s->elements[0]->type == FFI_TYPE_DOUBLE
       
  2283 @@ -347,7 +661,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
  2284    unsigned i;
       
  2285    ffi_type **ptr;
       
  2286    unsigned bytes;
       
  2287 -  int fparg_count = 0, intarg_count = 0;
       
  2288 +  unsigned fparg_count = 0, intarg_count = 0;
       
  2289    unsigned flags = 0;
       
  2290    unsigned size_al = 0;
       
  2291  
       
  2292 @@ -372,16 +686,25 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
  2293    /* Space for the frame pointer, callee's LR, CR, etc, and for
       
  2294       the asm's temp regs.  */
       
  2295  
       
  2296 -  bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
       
  2297 +  bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long);
       
  2298  
       
  2299 -  /* Return value handling.  The rules are as follows:
       
  2300 +  /* Return value handling.  
       
  2301 +    The rules m32 are as follows:
       
  2302       - 32-bit (or less) integer values are returned in gpr3;
       
  2303 -     - Structures of size <= 4 bytes also returned in gpr3;
       
  2304 -     - 64-bit integer values and structures between 5 and 8 bytes are returned
       
  2305 -       in gpr3 and gpr4;
       
  2306 +     - structures of size <= 4 bytes also returned in gpr3;
       
  2307 +     - 64-bit integer values [??? and structures between 5 and 8 bytes] are
       
  2308 +       returned in gpr3 and gpr4;
       
  2309       - Single/double FP values are returned in fpr1;
       
  2310       - Long double FP (if not equivalent to double) values are returned in
       
  2311         fpr1 and fpr2;
       
  2312 +     m64:
       
  2313 +     - 64-bit or smaller integral values are returned in GPR3
       
  2314 +     - Single/double FP values are returned in fpr1;
       
  2315 +     - Long double FP values are returned in fpr1 and fpr2;
       
  2316 +     m64 Structures:
       
  2317 +     - If the structure could be accommodated in registers were it to be the
       
  2318 +       first argument to a routine, then it is returned in those registers.
       
  2319 +     m32/m64 structures otherwise:
       
  2320       - Larger structures values are allocated space and a pointer is passed
       
  2321         as the first argument.  */
       
  2322    switch (cif->rtype->type)
       
  2323 @@ -410,9 +733,42 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
  2324        break;
       
  2325  
       
  2326      case FFI_TYPE_STRUCT:
       
  2327 +#if defined(POWERPC_DARWIN64)
       
  2328 +      {
       
  2329 +	/* Can we fit the struct into regs?  */
       
  2330 +	if (darwin64_struct_ret_by_value_p (cif->rtype))
       
  2331 +	  {
       
  2332 +	    unsigned nfpr = 0;
       
  2333 +	    flags |= FLAG_RETURNS_STRUCT;
       
  2334 +	    if (cif->rtype->size != 16)
       
  2335 +	      darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;
       
  2336 +	    else
       
  2337 +	      flags |= FLAG_RETURNS_128BITS;
       
  2338 +	    /* Will be 0 for 16byte struct.  */
       
  2339 +	    if (nfpr)
       
  2340 +	      flags |= FLAG_RETURNS_FP;
       
  2341 +	  }
       
  2342 +	else /* By ref. */
       
  2343 +	  {
       
  2344 +	    flags |= FLAG_RETVAL_REFERENCE;
       
  2345 +	    flags |= FLAG_RETURNS_NOTHING;
       
  2346 +	    intarg_count++;
       
  2347 +	  }
       
  2348 +      }
       
  2349 +#elif defined(DARWIN_PPC)
       
  2350 +      if (cif->rtype->size <= 4)
       
  2351 +	flags |= FLAG_RETURNS_STRUCT;
       
  2352 +      else /* else by reference.  */
       
  2353 +	{
       
  2354 +	  flags |= FLAG_RETVAL_REFERENCE;
       
  2355 +	  flags |= FLAG_RETURNS_NOTHING;
       
  2356 +	  intarg_count++;
       
  2357 +	}
       
  2358 +#else /* assume we pass by ref.  */
       
  2359        flags |= FLAG_RETVAL_REFERENCE;
       
  2360        flags |= FLAG_RETURNS_NOTHING;
       
  2361        intarg_count++;
       
  2362 +#endif
       
  2363        break;
       
  2364      case FFI_TYPE_VOID:
       
  2365        flags |= FLAG_RETURNS_NOTHING;
       
  2366 @@ -425,57 +781,83 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
  2367  
       
  2368    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
       
  2369       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
       
  2370 -     goes on the stack.  Structures are passed as a pointer to a copy of
       
  2371 -     the structure. Stuff on the stack needs to keep proper alignment.  */
       
  2372 +     goes on the stack.  
       
  2373 +     ??? Structures are passed as a pointer to a copy of the structure. 
       
  2374 +     Stuff on the stack needs to keep proper alignment.  
       
  2375 +     For m64 the count is effectively of half-GPRs.  */
       
  2376    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
       
  2377      {
       
  2378 +      unsigned align_words;
       
  2379        switch ((*ptr)->type)
       
  2380  	{
       
  2381  	case FFI_TYPE_FLOAT:
       
  2382  	case FFI_TYPE_DOUBLE:
       
  2383  	  fparg_count++;
       
  2384 +#if !defined(POWERPC_DARWIN64)
       
  2385  	  /* If this FP arg is going on the stack, it must be
       
  2386  	     8-byte-aligned.  */
       
  2387  	  if (fparg_count > NUM_FPR_ARG_REGISTERS
       
  2388 -	      && intarg_count%2 != 0)
       
  2389 +	      && (intarg_count & 0x01) != 0)
       
  2390  	    intarg_count++;
       
  2391 +#endif
       
  2392  	  break;
       
  2393  
       
  2394  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       
  2395 -
       
  2396  	case FFI_TYPE_LONGDOUBLE:
       
  2397  	  fparg_count += 2;
       
  2398  	  /* If this FP arg is going on the stack, it must be
       
  2399 -	     8-byte-aligned.  */
       
  2400 -	  if (fparg_count > NUM_FPR_ARG_REGISTERS
       
  2401 -	      && intarg_count%2 != 0)
       
  2402 -	    intarg_count++;
       
  2403 -	  intarg_count +=2;
       
  2404 +	     16-byte-aligned.  */
       
  2405 +	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
       
  2406 +#if defined (POWERPC64)
       
  2407 +	    intarg_count = ALIGN(intarg_count, 2);
       
  2408 +#else
       
  2409 +	    intarg_count = ALIGN(intarg_count, 4);
       
  2410 +#endif
       
  2411  	  break;
       
  2412  #endif
       
  2413  
       
  2414  	case FFI_TYPE_UINT64:
       
  2415  	case FFI_TYPE_SINT64:
       
  2416 +#if defined(POWERPC64)
       
  2417 +	  intarg_count++;
       
  2418 +#else
       
  2419  	  /* 'long long' arguments are passed as two words, but
       
  2420  	     either both words must fit in registers or both go
       
  2421  	     on the stack.  If they go on the stack, they must
       
  2422  	     be 8-byte-aligned.  */
       
  2423  	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
       
  2424 -	      || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
       
  2425 +	      || (intarg_count >= NUM_GPR_ARG_REGISTERS 
       
  2426 +	          && (intarg_count & 0x01) != 0))
       
  2427  	    intarg_count++;
       
  2428  	  intarg_count += 2;
       
  2429 +#endif
       
  2430  	  break;
       
  2431  
       
  2432  	case FFI_TYPE_STRUCT:
       
  2433  	  size_al = (*ptr)->size;
       
  2434 +#if defined(POWERPC_DARWIN64)
       
  2435 +	  align_words = (*ptr)->alignment >> 3;
       
  2436 +	  if (align_words)
       
  2437 +	    intarg_count = ALIGN(intarg_count, align_words);
       
  2438 +	  /* Base size of the struct.  */
       
  2439 +	  intarg_count += (size_al + 7) / 8;
       
  2440 +	  /* If 16 bytes then don't worry about floats.  */
       
  2441 +	  if (size_al != 16)
       
  2442 +	    /* Scan through for floats to be placed in regs.  */
       
  2443 +	    darwin64_scan_struct_for_floats (*ptr, &fparg_count) ;
       
  2444 +#else
       
  2445 +	  align_words = (*ptr)->alignment >> 2;
       
  2446 +	  if (align_words)
       
  2447 +	    intarg_count = ALIGN(intarg_count, align_words);
       
  2448  	  /* If the first member of the struct is a double, then align
       
  2449 -	     the struct to double-word.  */
       
  2450 +	     the struct to double-word. 
       
  2451  	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
       
  2452 -	    size_al = ALIGN((*ptr)->size, 8);
       
  2453 -#ifdef POWERPC64
       
  2454 +	    size_al = ALIGN((*ptr)->size, 8); */
       
  2455 +#  ifdef POWERPC64
       
  2456  	  intarg_count += (size_al + 7) / 8;
       
  2457 -#else
       
  2458 +#  else
       
  2459  	  intarg_count += (size_al + 3) / 4;
       
  2460 +#  endif
       
  2461  #endif
       
  2462  	  break;
       
  2463  
       
  2464 @@ -490,9 +872,18 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
  2465    if (fparg_count != 0)
       
  2466      flags |= FLAG_FP_ARGUMENTS;
       
  2467  
       
  2468 +#if defined(POWERPC_DARWIN64)
       
  2469 +  /* Space to image the FPR registers, if needed - which includes when they might be
       
  2470 +     used in a struct return.  */
       
  2471 +  if (fparg_count != 0 
       
  2472 +      || ((flags & FLAG_RETURNS_STRUCT)
       
  2473 +	   && (flags & FLAG_RETURNS_FP)))
       
  2474 +    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
       
  2475 +#else
       
  2476    /* Space for the FPR registers, if needed.  */
       
  2477    if (fparg_count != 0)
       
  2478      bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
       
  2479 +#endif
       
  2480  
       
  2481    /* Stack space.  */
       
  2482  #ifdef POWERPC64
       
  2483 @@ -506,7 +897,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
  2484      bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
       
  2485  
       
  2486    /* The stack space allocated needs to be a multiple of 16 bytes.  */
       
  2487 -  bytes = (bytes + 15) & ~0xF;
       
  2488 +  bytes = ALIGN(bytes, 16) ;
       
  2489  
       
  2490    cif->flags = flags;
       
  2491    cif->bytes = bytes;
       
  2492 @@ -516,8 +907,9 @@ ffi_prep_cif_machdep (ffi_cif *cif)
       
  2493  
       
  2494  extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
       
  2495  			 void (*fn)(void), void (*fn2)(void));
       
  2496 +
       
  2497  extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
       
  2498 -			    void (*fn)(void), void (*fn2)(void));
       
  2499 +			    void (*fn)(void), void (*fn2)(void), ffi_type*);
       
  2500  
       
  2501  void
       
  2502  ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
       
  2503 @@ -546,7 +938,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void)
       
  2504        break;
       
  2505      case FFI_DARWIN:
       
  2506        ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
       
  2507 -		      FFI_FN(ffi_prep_args));
       
  2508 +		      FFI_FN(ffi_prep_args), cif->rtype);
       
  2509        break;
       
  2510      default:
       
  2511        FFI_ASSERT(0);
       
  2512 @@ -566,58 +958,48 @@ typedef struct aix_fd_struct {
       
  2513  } aix_fd;
       
  2514  
       
  2515  /* here I'd like to add the stack frame layout we use in darwin_closure.S
       
  2516 -   and aix_clsoure.S
       
  2517 +   and aix_closure.S
       
  2518 +
       
  2519 +   m32/m64
       
  2520  
       
  2521 -   SP previous -> +---------------------------------------+ <--- child frame
       
  2522 -		  | back chain to caller 4                |
       
  2523 -		  +---------------------------------------+ 4
       
  2524 -		  | saved CR 4                            |
       
  2525 -		  +---------------------------------------+ 8
       
  2526 -		  | saved LR 4                            |
       
  2527 -		  +---------------------------------------+ 12
       
  2528 -		  | reserved for compilers 4              |
       
  2529 -		  +---------------------------------------+ 16
       
  2530 -		  | reserved for binders 4                |
       
  2531 -		  +---------------------------------------+ 20
       
  2532 -		  | saved TOC pointer 4                   |
       
  2533 -		  +---------------------------------------+ 24
       
  2534 -		  | always reserved 8*4=32 (previous GPRs)|
       
  2535 -		  | according to the linkage convention   |
       
  2536 -		  | from AIX                              |
       
  2537 -		  +---------------------------------------+ 56
       
  2538 -		  | our FPR area 13*8=104                 |
       
  2539 -		  | f1                                    |
       
  2540 -		  | .                                     |
       
  2541 -		  | f13                                   |
       
  2542 -		  +---------------------------------------+ 160
       
  2543 -		  | result area 8                         |
       
  2544 -		  +---------------------------------------+ 168
       
  2545 -		  | alignement to the next multiple of 16 |
       
  2546 -SP current -->    +---------------------------------------+ 176 <- parent frame
       
  2547 -		  | back chain to caller 4                |
       
  2548 -		  +---------------------------------------+ 180
       
  2549 -		  | saved CR 4                            |
       
  2550 -		  +---------------------------------------+ 184
       
  2551 -		  | saved LR 4                            |
       
  2552 -		  +---------------------------------------+ 188
       
  2553 -		  | reserved for compilers 4              |
       
  2554 -		  +---------------------------------------+ 192
       
  2555 -		  | reserved for binders 4                |
       
  2556 -		  +---------------------------------------+ 196
       
  2557 -		  | saved TOC pointer 4                   |
       
  2558 -		  +---------------------------------------+ 200
       
  2559 -		  | always reserved 8*4=32  we store our  |
       
  2560 -		  | GPRs here                             |
       
  2561 -		  | r3                                    |
       
  2562 -		  | .                                     |
       
  2563 -		  | r10                                   |
       
  2564 -		  +---------------------------------------+ 232
       
  2565 -		  | overflow part                         |
       
  2566 -		  +---------------------------------------+ xxx
       
  2567 -		  | ????                                  |
       
  2568 -		  +---------------------------------------+ xxx
       
  2569 +   The stack layout looks like this:
       
  2570 +
       
  2571 +   |   Additional params...			| |     Higher address
       
  2572 +   ~						~ ~
       
  2573 +   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
       
  2574 +   |--------------------------------------------| |
       
  2575 +   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
       
  2576 +   |--------------------------------------------| |
       
  2577 +   |   Reserved                       2*4/8	| |
       
  2578 +   |--------------------------------------------| |
       
  2579 +   |   Space for callee's LR		4/8	| |
       
  2580 +   |--------------------------------------------| |
       
  2581 +   |   Saved CR [low word for m64]      4/8	| |
       
  2582 +   |--------------------------------------------| |
       
  2583 +   |   Current backchain pointer	4/8	|-/ Parent's frame.
       
  2584 +   |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM
       
  2585 +   |   Result Bytes			16	| |
       
  2586 +   |--------------------------------------------| |
       
  2587 +   ~   padding to 16-byte alignment		~ ~
       
  2588 +   |--------------------------------------------| |
       
  2589 +   |   NUM_FPR_ARG_REGISTERS slots		| |
       
  2590 +   |   here fp13 .. fp1		       13*8	| |
       
  2591 +   |--------------------------------------------| |
       
  2592 +   |   R3..R10			  8*4/8=32/64	| | NUM_GPR_ARG_REGISTERS
       
  2593 +   |--------------------------------------------| |
       
  2594 +   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
       
  2595 +   |--------------------------------------------| |	stack	|
       
  2596 +   |   Reserved [compiler,binder]     2*4/8	| |	grows	|
       
  2597 +   |--------------------------------------------| |	down	V
       
  2598 +   |   Space for callee's LR		4/8	| |
       
  2599 +   |--------------------------------------------| |	lower addresses
       
  2600 +   |   Saved CR [low word for m64]      4/8	| |
       
  2601 +   |--------------------------------------------| |     stack pointer here
       
  2602 +   |   Current backchain pointer	4/8	|-/	during
       
  2603 +   |--------------------------------------------|   <<<	ffi_closure_ASM.
       
  2604  
       
  2605  */
       
  2606 +
       
  2607  ffi_status
       
  2608  ffi_prep_closure_loc (ffi_closure* closure,
       
  2609  		      ffi_cif* cif,
       
  2610 @@ -631,30 +1013,44 @@ ffi_prep_closure_loc (ffi_closure* closu
       
  2611  
       
  2612    switch (cif->abi)
       
  2613      {
       
  2614 -    case FFI_DARWIN:
       
  2615 +      case FFI_DARWIN:
       
  2616  
       
  2617 -      FFI_ASSERT (cif->abi == FFI_DARWIN);
       
  2618 +	FFI_ASSERT (cif->abi == FFI_DARWIN);
       
  2619  
       
  2620 -      tramp = (unsigned int *) &closure->tramp[0];
       
  2621 -      tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
       
  2622 -      tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
       
  2623 -      tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
       
  2624 -      tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
       
  2625 -      tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
       
  2626 -      tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
       
  2627 -      tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
       
  2628 -      tramp[9] = 0x4e800420;  /*   bctr  */
       
  2629 -      tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
       
  2630 -      tramp[3] = (unsigned long) codeloc; /* context  */
       
  2631 +	tramp = (unsigned int *) &closure->tramp[0];
       
  2632 +#if defined(POWERPC_DARWIN64)
       
  2633 +	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
       
  2634 +	tramp[1] = 0x429f0015;  /*   bcl-    20,4*cr7+so,  +0x18 (L1)  */
       
  2635 +	/* We put the addresses here.  */
       
  2636 +	tramp[6] = 0x7d6802a6;  /*L1:   mflr    r11  */
       
  2637 +	tramp[7] = 0xe98b0000;  /*   ld     r12,0(r11) function address  */
       
  2638 +	tramp[8] = 0x7c0803a6;  /*   mtlr    r0   */
       
  2639 +	tramp[9] = 0x7d8903a6;  /*   mtctr   r12  */
       
  2640 +	tramp[10] = 0xe96b0008;  /*   lwz     r11,8(r11) static chain  */
       
  2641 +	tramp[11] = 0x4e800420;  /*   bctr  */
       
  2642  
       
  2643 -      closure->cif = cif;
       
  2644 -      closure->fun = fun;
       
  2645 -      closure->user_data = user_data;
       
  2646 +	*((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function  */
       
  2647 +	*((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context  */
       
  2648 +#else
       
  2649 +	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
       
  2650 +	tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
       
  2651 +	tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
       
  2652 +	tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
       
  2653 +	tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
       
  2654 +	tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
       
  2655 +	tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
       
  2656 +	tramp[9] = 0x4e800420;  /*   bctr  */
       
  2657 +	tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
       
  2658 +	tramp[3] = (unsigned long) codeloc; /* context  */
       
  2659 +#endif
       
  2660 +	closure->cif = cif;
       
  2661 +	closure->fun = fun;
       
  2662 +	closure->user_data = user_data;
       
  2663  
       
  2664 -      /* Flush the icache. Only necessary on Darwin.  */
       
  2665 -      flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
       
  2666 +	/* Flush the icache. Only necessary on Darwin.  */
       
  2667 +	flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
       
  2668  
       
  2669 -      break;
       
  2670 +	break;
       
  2671  
       
  2672      case FFI_AIX:
       
  2673  
       
  2674 @@ -669,10 +1065,10 @@ ffi_prep_closure_loc (ffi_closure* closu
       
  2675        closure->cif = cif;
       
  2676        closure->fun = fun;
       
  2677        closure->user_data = user_data;
       
  2678 +      break;
       
  2679  
       
  2680      default:
       
  2681 -
       
  2682 -      FFI_ASSERT(0);
       
  2683 +      return FFI_BAD_ABI;
       
  2684        break;
       
  2685      }
       
  2686    return FFI_OK;
       
  2687 @@ -708,7 +1104,7 @@ typedef union
       
  2688    double d;
       
  2689  } ffi_dblfl;
       
  2690  
       
  2691 -int
       
  2692 +ffi_type *
       
  2693  ffi_closure_helper_DARWIN (ffi_closure *, void *,
       
  2694  			   unsigned long *, ffi_dblfl *);
       
  2695  
       
  2696 @@ -719,7 +1115,7 @@ ffi_closure_helper_DARWIN (ffi_closure *
       
  2697     up space for a return value, ffi_closure_ASM invokes the
       
  2698     following helper function to do most of the work.  */
       
  2699  
       
  2700 -int
       
  2701 +ffi_type *
       
  2702  ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
       
  2703  			   unsigned long *pgr, ffi_dblfl *pfr)
       
  2704  {
       
  2705 @@ -741,16 +1137,32 @@ ffi_closure_helper_DARWIN (ffi_closure *
       
  2706    ffi_cif *        cif;
       
  2707    ffi_dblfl *      end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
       
  2708    unsigned         size_al;
       
  2709 +#if defined(POWERPC_DARWIN64)
       
  2710 +  unsigned 	   fpsused = 0;
       
  2711 +#endif
       
  2712  
       
  2713    cif = closure->cif;
       
  2714    avalue = alloca (cif->nargs * sizeof(void *));
       
  2715  
       
  2716 -  /* Copy the caller's structure return value address so that the closure
       
  2717 -     returns the data directly to the caller.  */
       
  2718    if (cif->rtype->type == FFI_TYPE_STRUCT)
       
  2719      {
       
  2720 +#if defined(POWERPC_DARWIN64)
       
  2721 +      if (!darwin64_struct_ret_by_value_p (cif->rtype))
       
  2722 +	{
       
  2723 +    	  /* Won't fit into the regs - return by ref.  */
       
  2724 +	  rvalue = (void *) *pgr;
       
  2725 +	  pgr++;
       
  2726 +	}
       
  2727 +#elif defined(DARWIN_PPC)
       
  2728 +      if (cif->rtype->size > 4)
       
  2729 +	{
       
  2730 +	  rvalue = (void *) *pgr;
       
  2731 +	  pgr++;
       
  2732 +	}
       
  2733 +#else /* assume we return by ref.  */
       
  2734        rvalue = (void *) *pgr;
       
  2735        pgr++;
       
  2736 +#endif
       
  2737      }
       
  2738  
       
  2739    i = 0;
       
  2740 @@ -764,7 +1176,7 @@ ffi_closure_helper_DARWIN (ffi_closure *
       
  2741  	{
       
  2742  	case FFI_TYPE_SINT8:
       
  2743  	case FFI_TYPE_UINT8:
       
  2744 -#ifdef POWERPC64
       
  2745 +#if  defined(POWERPC64)
       
  2746  	  avalue[i] = (char *) pgr + 7;
       
  2747  #else
       
  2748  	  avalue[i] = (char *) pgr + 3;
       
  2749 @@ -774,7 +1186,7 @@ ffi_closure_helper_DARWIN (ffi_closure *
       
  2750  
       
  2751  	case FFI_TYPE_SINT16:
       
  2752  	case FFI_TYPE_UINT16:
       
  2753 -#ifdef POWERPC64
       
  2754 +#if  defined(POWERPC64)
       
  2755  	  avalue[i] = (char *) pgr + 6;
       
  2756  #else
       
  2757  	  avalue[i] = (char *) pgr + 2;
       
  2758 @@ -784,7 +1196,7 @@ ffi_closure_helper_DARWIN (ffi_closure *
       
  2759  
       
  2760  	case FFI_TYPE_SINT32:
       
  2761  	case FFI_TYPE_UINT32:
       
  2762 -#ifdef POWERPC64
       
  2763 +#if  defined(POWERPC64)
       
  2764  	  avalue[i] = (char *) pgr + 4;
       
  2765  #else
       
  2766  	case FFI_TYPE_POINTER:
       
  2767 @@ -794,34 +1206,53 @@ ffi_closure_helper_DARWIN (ffi_closure *
       
  2768  	  break;
       
  2769  
       
  2770  	case FFI_TYPE_STRUCT:
       
  2771 -#ifdef POWERPC64
       
  2772  	  size_al = arg_types[i]->size;
       
  2773 -	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
       
  2774 -	    size_al = ALIGN (arg_types[i]->size, 8);
       
  2775 -	  if (size_al < 3 && cif->abi == FFI_DARWIN)
       
  2776 -	    avalue[i] = (char *) pgr + 8 - size_al;
       
  2777 -	  else
       
  2778 -	    avalue[i] = pgr;
       
  2779 +#if defined(POWERPC_DARWIN64)
       
  2780 +	  pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment);
       
  2781 +	  if (size_al < 3 || size_al == 4)
       
  2782 +	    {
       
  2783 +	      avalue[i] = ((char *)pgr)+8-size_al;
       
  2784 +	      if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT
       
  2785 +		  && fpsused < NUM_FPR_ARG_REGISTERS)
       
  2786 +		{
       
  2787 +		  *(float *)pgr = (float) *(double *)pfr;
       
  2788 +		  pfr++;
       
  2789 +		  fpsused++;
       
  2790 +		}
       
  2791 +	    }
       
  2792 +	  else 
       
  2793 +	    {
       
  2794 +	      if (size_al != 16)
       
  2795 +		pfr = (ffi_dblfl *) 
       
  2796 +		    darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr,
       
  2797 +						   (double *)pfr, &fpsused);
       
  2798 +	      avalue[i] = pgr;
       
  2799 +	    }
       
  2800  	  pgr += (size_al + 7) / 8;
       
  2801  #else
       
  2802 -	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
       
  2803 -	     SI 4 bytes) are aligned as if they were those modes.  */
       
  2804 -	  size_al = arg_types[i]->size;
       
  2805  	  /* If the first member of the struct is a double, then align
       
  2806  	     the struct to double-word.  */
       
  2807  	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
       
  2808  	    size_al = ALIGN(arg_types[i]->size, 8);
       
  2809 +#  if defined(POWERPC64)
       
  2810 +	  FFI_ASSERT (cif->abi != FFI_DARWIN);
       
  2811 +	  avalue[i] = pgr;
       
  2812 +	  pgr += (size_al + 7) / 8;
       
  2813 +#  else
       
  2814 +	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
       
  2815 +	     SI 4 bytes) are aligned as if they were those modes.  */
       
  2816  	  if (size_al < 3 && cif->abi == FFI_DARWIN)
       
  2817  	    avalue[i] = (char*) pgr + 4 - size_al;
       
  2818  	  else
       
  2819  	    avalue[i] = pgr;
       
  2820  	  pgr += (size_al + 3) / 4;
       
  2821 +#  endif
       
  2822  #endif
       
  2823  	  break;
       
  2824  
       
  2825  	case FFI_TYPE_SINT64:
       
  2826  	case FFI_TYPE_UINT64:
       
  2827 -#ifdef POWERPC64
       
  2828 +#if  defined(POWERPC64)
       
  2829  	case FFI_TYPE_POINTER:
       
  2830  	  avalue[i] = pgr;
       
  2831  	  pgr++;
       
  2832 @@ -924,5 +1355,5 @@ ffi_closure_helper_DARWIN (ffi_closure *
       
  2833    (closure->fun) (cif, rvalue, avalue, closure->user_data);
       
  2834  
       
  2835    /* Tell ffi_closure_ASM to perform return type promotions.  */
       
  2836 -  return cif->rtype->type;
       
  2837 +  return cif->rtype;
       
  2838  }
       
  2839 --- mozilla/js/src/ctypes/libffi/src/powerpc/ffitarget.h	2013-10-24 09:56:51.847587813 +0200
       
  2840 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/ffitarget.h	2013-11-29 17:23:26.000000000 +0100
       
  2841 @@ -1,6 +1,8 @@
       
  2842  /* -----------------------------------------------------------------*-C-*-
       
  2843 -   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
       
  2844 -   Copyright (C) 2007, 2008 Free Software Foundation, Inc
       
  2845 +   ffitarget.h - Copyright (c) 2012  Anthony Green
       
  2846 +                 Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
       
  2847 +                 Copyright (c) 1996-2003  Red Hat, Inc.
       
  2848 +
       
  2849     Target configuration macros for PowerPC.
       
  2850  
       
  2851     Permission is hereby granted, free of charge, to any person obtaining
       
  2852 @@ -28,16 +30,23 @@
       
  2853  #ifndef LIBFFI_TARGET_H
       
  2854  #define LIBFFI_TARGET_H
       
  2855  
       
  2856 +#ifndef LIBFFI_H
       
  2857 +#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
       
  2858 +#endif
       
  2859 +
       
  2860  /* ---- System specific configurations ----------------------------------- */
       
  2861  
       
  2862  #if defined (POWERPC) && defined (__powerpc64__)	/* linux64 */
       
  2863  #ifndef POWERPC64
       
  2864  #define POWERPC64
       
  2865  #endif
       
  2866 -#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin */
       
  2867 +#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin64 */
       
  2868  #ifndef POWERPC64
       
  2869  #define POWERPC64
       
  2870  #endif
       
  2871 +#ifndef POWERPC_DARWIN64
       
  2872 +#define POWERPC_DARWIN64
       
  2873 +#endif
       
  2874  #elif defined (POWERPC_AIX) && defined (__64BIT__)	/* AIX64 */
       
  2875  #ifndef POWERPC64
       
  2876  #define POWERPC64
       
  2877 @@ -57,18 +66,14 @@ typedef enum ffi_abi {
       
  2878    FFI_LINUX64,
       
  2879    FFI_LINUX,
       
  2880    FFI_LINUX_SOFT_FLOAT,
       
  2881 -# ifdef POWERPC64
       
  2882 +# if defined(POWERPC64)
       
  2883    FFI_DEFAULT_ABI = FFI_LINUX64,
       
  2884 -# else
       
  2885 -#  if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
       
  2886 -  FFI_DEFAULT_ABI = FFI_LINUX,
       
  2887 -#  else
       
  2888 -#   ifdef __NO_FPRS__
       
  2889 +# elif defined(__NO_FPRS__)
       
  2890    FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
       
  2891 -#   else
       
  2892 +# elif (__LDBL_MANT_DIG__ == 106)
       
  2893 +  FFI_DEFAULT_ABI = FFI_LINUX,
       
  2894 +# else
       
  2895    FFI_DEFAULT_ABI = FFI_GCC_SYSV,
       
  2896 -#   endif
       
  2897 -#  endif
       
  2898  # endif
       
  2899  #endif
       
  2900  
       
  2901 @@ -101,6 +106,10 @@ typedef enum ffi_abi {
       
  2902  
       
  2903  #define FFI_CLOSURES 1
       
  2904  #define FFI_NATIVE_RAW_API 0
       
  2905 +#if defined (POWERPC) || defined (POWERPC_FREEBSD)
       
  2906 +# define FFI_TARGET_SPECIFIC_VARIADIC 1
       
  2907 +# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
       
  2908 +#endif
       
  2909  
       
  2910  /* For additional types like the below, take care about the order in
       
  2911     ppc_closures.S. They must follow after the FFI_TYPE_LAST.  */
       
  2912 @@ -113,10 +122,23 @@ typedef enum ffi_abi {
       
  2913     defined in ffi.c, to determine the exact return type and its size.  */
       
  2914  #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
       
  2915  
       
  2916 -#if defined(POWERPC64) || defined(POWERPC_AIX)
       
  2917 -#define FFI_TRAMPOLINE_SIZE 24
       
  2918 -#else /* POWERPC || POWERPC_AIX */
       
  2919 -#define FFI_TRAMPOLINE_SIZE 40
       
  2920 +/* Used by ELFv2 for homogenous structure returns.  */
       
  2921 +#define FFI_V2_TYPE_FLOAT_HOMOG		(FFI_TYPE_LAST + 1)
       
  2922 +#define FFI_V2_TYPE_DOUBLE_HOMOG	(FFI_TYPE_LAST + 2)
       
  2923 +#define FFI_V2_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 3)
       
  2924 +
       
  2925 +#if _CALL_ELF == 2
       
  2926 +# define FFI_TRAMPOLINE_SIZE 32
       
  2927 +#else
       
  2928 +# if defined(POWERPC64) || defined(POWERPC_AIX)
       
  2929 +#  if defined(POWERPC_DARWIN64)
       
  2930 +#    define FFI_TRAMPOLINE_SIZE 48
       
  2931 +#  else
       
  2932 +#    define FFI_TRAMPOLINE_SIZE 24
       
  2933 +#  endif
       
  2934 +# else /* POWERPC || POWERPC_AIX */
       
  2935 +#  define FFI_TRAMPOLINE_SIZE 40
       
  2936 +# endif
       
  2937  #endif
       
  2938  
       
  2939  #ifndef LIBFFI_ASM
       
  2940 --- mozilla/js/src/ctypes/libffi/src/powerpc/linux64_closure.S	2013-10-24 09:56:51.847587813 +0200
       
  2941 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/linux64_closure.S	2013-11-29 17:23:26.000000000 +0100
       
  2942 @@ -32,66 +32,127 @@
       
  2943  
       
  2944  #ifdef __powerpc64__
       
  2945  	FFI_HIDDEN (ffi_closure_LINUX64)
       
  2946 -	FFI_HIDDEN (.ffi_closure_LINUX64)
       
  2947 -	.globl  ffi_closure_LINUX64, .ffi_closure_LINUX64
       
  2948 +	.globl  ffi_closure_LINUX64
       
  2949 +# if _CALL_ELF == 2
       
  2950 +	.text
       
  2951 +ffi_closure_LINUX64:
       
  2952 +	addis	%r2, %r12, .TOC.-ffi_closure_LINUX64@ha
       
  2953 +	addi	%r2, %r2, .TOC.-ffi_closure_LINUX64@l
       
  2954 +	.localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64
       
  2955 +# else
       
  2956  	.section        ".opd","aw"
       
  2957  	.align  3
       
  2958  ffi_closure_LINUX64:
       
  2959 +#  ifdef _CALL_LINUX
       
  2960 +	.quad   .L.ffi_closure_LINUX64,.TOC.@tocbase,0
       
  2961 +	.type   ffi_closure_LINUX64,@function
       
  2962 +	.text
       
  2963 +.L.ffi_closure_LINUX64:
       
  2964 +#  else
       
  2965 +	FFI_HIDDEN (.ffi_closure_LINUX64)
       
  2966 +	.globl  .ffi_closure_LINUX64
       
  2967  	.quad   .ffi_closure_LINUX64,.TOC.@tocbase,0
       
  2968  	.size   ffi_closure_LINUX64,24
       
  2969  	.type   .ffi_closure_LINUX64,@function
       
  2970  	.text
       
  2971  .ffi_closure_LINUX64:
       
  2972 +#  endif
       
  2973 +# endif
       
  2974 +
       
  2975 +# if _CALL_ELF == 2
       
  2976 +#  32 byte special reg save area + 64 byte parm save area and retval
       
  2977 +#  + 13*8 fpr save area + round to 16
       
  2978 +#  define STACKFRAME 208
       
  2979 +#  define PARMSAVE 32
       
  2980 +#  No parameter save area is needed for the call to ffi_closure_helper_LINUX64,
       
  2981 +#  so return value can start there.
       
  2982 +#  define RETVAL PARMSAVE
       
  2983 +# else
       
  2984 +#  48 bytes special reg save area + 64 bytes parm save area
       
  2985 +#  + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
       
  2986 +#  define STACKFRAME 240
       
  2987 +#  define PARMSAVE 48
       
  2988 +#  define RETVAL PARMSAVE+64
       
  2989 +# endif
       
  2990 +
       
  2991  .LFB1:
       
  2992 -	# save general regs into parm save area
       
  2993 -	std	%r3, 48(%r1)
       
  2994 -	std	%r4, 56(%r1)
       
  2995 -	std	%r5, 64(%r1)
       
  2996 -	std	%r6, 72(%r1)
       
  2997 +# if _CALL_ELF == 2
       
  2998 +	ld	%r12, FFI_TRAMPOLINE_SIZE(%r11)		# closure->cif
       
  2999 +	mflr	%r0
       
  3000 +	lwz	%r12, 28(%r12)				# cif->flags
       
  3001 +	mtcrf	0x40, %r12
       
  3002 +	addi	%r12, %r1, PARMSAVE
       
  3003 +	bt	7, .Lparmsave
       
  3004 +	# Our caller has not allocated a parameter save area.
       
  3005 +	# We need to allocate one here and use it to pass gprs to
       
  3006 +	# ffi_closure_helper_LINUX64.  The return value area will do.
       
  3007 +	addi	%r12, %r1, -STACKFRAME+RETVAL
       
  3008 +.Lparmsave:
       
  3009 +	std	%r0, 16(%r1)
       
  3010 +	# Save general regs into parm save area
       
  3011 +	std	%r3, 0(%r12)
       
  3012 +	std	%r4, 8(%r12)
       
  3013 +	std	%r5, 16(%r12)
       
  3014 +	std	%r6, 24(%r12)
       
  3015 +	std	%r7, 32(%r12)
       
  3016 +	std	%r8, 40(%r12)
       
  3017 +	std	%r9, 48(%r12)
       
  3018 +	std	%r10, 56(%r12)
       
  3019 +
       
  3020 +	# load up the pointer to the parm save area
       
  3021 +	mr	%r5, %r12
       
  3022 +# else
       
  3023  	mflr	%r0
       
  3024 +	# Save general regs into parm save area
       
  3025 +	# This is the parameter save area set up by our caller.
       
  3026 +	std	%r3, PARMSAVE+0(%r1)
       
  3027 +	std	%r4, PARMSAVE+8(%r1)
       
  3028 +	std	%r5, PARMSAVE+16(%r1)
       
  3029 +	std	%r6, PARMSAVE+24(%r1)
       
  3030 +	std	%r7, PARMSAVE+32(%r1)
       
  3031 +	std	%r8, PARMSAVE+40(%r1)
       
  3032 +	std	%r9, PARMSAVE+48(%r1)
       
  3033 +	std	%r10, PARMSAVE+56(%r1)
       
  3034  
       
  3035 -	std	%r7, 80(%r1)
       
  3036 -	std	%r8, 88(%r1)
       
  3037 -	std	%r9, 96(%r1)
       
  3038 -	std	%r10, 104(%r1)
       
  3039  	std	%r0, 16(%r1)
       
  3040  
       
  3041 -	# mandatory 48 bytes special reg save area + 64 bytes parm save area
       
  3042 -	# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
       
  3043 -	stdu	%r1, -240(%r1)
       
  3044 -.LCFI0:
       
  3045 +	# load up the pointer to the parm save area
       
  3046 +	addi	%r5, %r1, PARMSAVE
       
  3047 +# endif
       
  3048  
       
  3049  	# next save fpr 1 to fpr 13
       
  3050 -	stfd  %f1, 128+(0*8)(%r1)
       
  3051 -	stfd  %f2, 128+(1*8)(%r1)
       
  3052 -	stfd  %f3, 128+(2*8)(%r1)
       
  3053 -	stfd  %f4, 128+(3*8)(%r1)
       
  3054 -	stfd  %f5, 128+(4*8)(%r1)
       
  3055 -	stfd  %f6, 128+(5*8)(%r1)
       
  3056 -	stfd  %f7, 128+(6*8)(%r1)
       
  3057 -	stfd  %f8, 128+(7*8)(%r1)
       
  3058 -	stfd  %f9, 128+(8*8)(%r1)
       
  3059 -	stfd  %f10, 128+(9*8)(%r1)
       
  3060 -	stfd  %f11, 128+(10*8)(%r1)
       
  3061 -	stfd  %f12, 128+(11*8)(%r1)
       
  3062 -	stfd  %f13, 128+(12*8)(%r1)
       
  3063 +	stfd	%f1, -104+(0*8)(%r1)
       
  3064 +	stfd	%f2, -104+(1*8)(%r1)
       
  3065 +	stfd	%f3, -104+(2*8)(%r1)
       
  3066 +	stfd	%f4, -104+(3*8)(%r1)
       
  3067 +	stfd	%f5, -104+(4*8)(%r1)
       
  3068 +	stfd	%f6, -104+(5*8)(%r1)
       
  3069 +	stfd	%f7, -104+(6*8)(%r1)
       
  3070 +	stfd	%f8, -104+(7*8)(%r1)
       
  3071 +	stfd	%f9, -104+(8*8)(%r1)
       
  3072 +	stfd	%f10, -104+(9*8)(%r1)
       
  3073 +	stfd	%f11, -104+(10*8)(%r1)
       
  3074 +	stfd	%f12, -104+(11*8)(%r1)
       
  3075 +	stfd	%f13, -104+(12*8)(%r1)
       
  3076  
       
  3077 -	# set up registers for the routine that actually does the work
       
  3078 -	# get the context pointer from the trampoline
       
  3079 -	mr %r3, %r11
       
  3080 +	# load up the pointer to the saved fpr registers */
       
  3081 +	addi	%r6, %r1, -104
       
  3082  
       
  3083 -	# now load up the pointer to the result storage
       
  3084 -	addi %r4, %r1, 112
       
  3085 +	# load up the pointer to the result storage
       
  3086 +	addi	%r4, %r1, -STACKFRAME+RETVAL
       
  3087  
       
  3088 -	# now load up the pointer to the parameter save area
       
  3089 -	# in the previous frame
       
  3090 -	addi %r5, %r1, 240 + 48
       
  3091 +	stdu	%r1, -STACKFRAME(%r1)
       
  3092 +.LCFI0:
       
  3093  
       
  3094 -	# now load up the pointer to the saved fpr registers */
       
  3095 -	addi %r6, %r1, 128
       
  3096 +	# get the context pointer from the trampoline
       
  3097 +	mr	%r3, %r11
       
  3098  
       
  3099  	# make the call
       
  3100 +# if defined _CALL_LINUX || _CALL_ELF == 2
       
  3101 +	bl ffi_closure_helper_LINUX64
       
  3102 +# else
       
  3103  	bl .ffi_closure_helper_LINUX64
       
  3104 +# endif
       
  3105  .Lret:
       
  3106  
       
  3107  	# now r3 contains the return type
       
  3108 @@ -100,10 +161,12 @@ ffi_closure_LINUX64:
       
  3109  
       
  3110  	# look up the proper starting point in table
       
  3111  	# by using return type as offset
       
  3112 +	ld %r0, STACKFRAME+16(%r1)
       
  3113 +	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT
       
  3114 +	bge .Lsmall
       
  3115  	mflr %r4		# move address of .Lret to r4
       
  3116  	sldi %r3, %r3, 4	# now multiply return type by 16
       
  3117  	addi %r4, %r4, .Lret_type0 - .Lret
       
  3118 -	ld %r0, 240+16(%r1)
       
  3119  	add %r3, %r3, %r4	# add contents of table to table address
       
  3120  	mtctr %r3
       
  3121  	bctr			# jump to it
       
  3122 @@ -116,85 +179,175 @@ ffi_closure_LINUX64:
       
  3123  .Lret_type0:
       
  3124  # case FFI_TYPE_VOID
       
  3125  	mtlr %r0
       
  3126 -	addi %r1, %r1, 240
       
  3127 +	addi %r1, %r1, STACKFRAME
       
  3128  	blr
       
  3129  	nop
       
  3130  # case FFI_TYPE_INT
       
  3131 -	lwa %r3, 112+4(%r1)
       
  3132 +# ifdef __LITTLE_ENDIAN__
       
  3133 +	lwa %r3, RETVAL+0(%r1)
       
  3134 +# else
       
  3135 +	lwa %r3, RETVAL+4(%r1)
       
  3136 +# endif
       
  3137  	mtlr %r0
       
  3138 -	addi %r1, %r1, 240
       
  3139 +	addi %r1, %r1, STACKFRAME
       
  3140  	blr
       
  3141  # case FFI_TYPE_FLOAT
       
  3142 -	lfs %f1, 112+0(%r1)
       
  3143 +	lfs %f1, RETVAL+0(%r1)
       
  3144  	mtlr %r0
       
  3145 -	addi %r1, %r1, 240
       
  3146 +	addi %r1, %r1, STACKFRAME
       
  3147  	blr
       
  3148  # case FFI_TYPE_DOUBLE
       
  3149 -	lfd %f1, 112+0(%r1)
       
  3150 +	lfd %f1, RETVAL+0(%r1)
       
  3151  	mtlr %r0
       
  3152 -	addi %r1, %r1, 240
       
  3153 +	addi %r1, %r1, STACKFRAME
       
  3154  	blr
       
  3155  # case FFI_TYPE_LONGDOUBLE
       
  3156 -	lfd %f1, 112+0(%r1)
       
  3157 +	lfd %f1, RETVAL+0(%r1)
       
  3158  	mtlr %r0
       
  3159 -	lfd %f2, 112+8(%r1)
       
  3160 +	lfd %f2, RETVAL+8(%r1)
       
  3161  	b .Lfinish
       
  3162  # case FFI_TYPE_UINT8
       
  3163 -	lbz %r3, 112+7(%r1)
       
  3164 +# ifdef __LITTLE_ENDIAN__
       
  3165 +	lbz %r3, RETVAL+0(%r1)
       
  3166 +# else
       
  3167 +	lbz %r3, RETVAL+7(%r1)
       
  3168 +# endif
       
  3169  	mtlr %r0
       
  3170 -	addi %r1, %r1, 240
       
  3171 +	addi %r1, %r1, STACKFRAME
       
  3172  	blr
       
  3173  # case FFI_TYPE_SINT8
       
  3174 -	lbz %r3, 112+7(%r1)
       
  3175 +# ifdef __LITTLE_ENDIAN__
       
  3176 +	lbz %r3, RETVAL+0(%r1)
       
  3177 +# else
       
  3178 +	lbz %r3, RETVAL+7(%r1)
       
  3179 +# endif
       
  3180  	extsb %r3,%r3
       
  3181  	mtlr %r0
       
  3182  	b .Lfinish
       
  3183  # case FFI_TYPE_UINT16
       
  3184 -	lhz %r3, 112+6(%r1)
       
  3185 +# ifdef __LITTLE_ENDIAN__
       
  3186 +	lhz %r3, RETVAL+0(%r1)
       
  3187 +# else
       
  3188 +	lhz %r3, RETVAL+6(%r1)
       
  3189 +# endif
       
  3190  	mtlr %r0
       
  3191  .Lfinish:
       
  3192 -	addi %r1, %r1, 240
       
  3193 +	addi %r1, %r1, STACKFRAME
       
  3194  	blr
       
  3195  # case FFI_TYPE_SINT16
       
  3196 -	lha %r3, 112+6(%r1)
       
  3197 +# ifdef __LITTLE_ENDIAN__
       
  3198 +	lha %r3, RETVAL+0(%r1)
       
  3199 +# else
       
  3200 +	lha %r3, RETVAL+6(%r1)
       
  3201 +# endif
       
  3202  	mtlr %r0
       
  3203 -	addi %r1, %r1, 240
       
  3204 +	addi %r1, %r1, STACKFRAME
       
  3205  	blr
       
  3206  # case FFI_TYPE_UINT32
       
  3207 -	lwz %r3, 112+4(%r1)
       
  3208 +# ifdef __LITTLE_ENDIAN__
       
  3209 +	lwz %r3, RETVAL+0(%r1)
       
  3210 +# else
       
  3211 +	lwz %r3, RETVAL+4(%r1)
       
  3212 +# endif
       
  3213  	mtlr %r0
       
  3214 -	addi %r1, %r1, 240
       
  3215 +	addi %r1, %r1, STACKFRAME
       
  3216  	blr
       
  3217  # case FFI_TYPE_SINT32
       
  3218 -	lwa %r3, 112+4(%r1)
       
  3219 +# ifdef __LITTLE_ENDIAN__
       
  3220 +	lwa %r3, RETVAL+0(%r1)
       
  3221 +# else
       
  3222 +	lwa %r3, RETVAL+4(%r1)
       
  3223 +# endif
       
  3224  	mtlr %r0
       
  3225 -	addi %r1, %r1, 240
       
  3226 +	addi %r1, %r1, STACKFRAME
       
  3227  	blr
       
  3228  # case FFI_TYPE_UINT64
       
  3229 -	ld %r3, 112+0(%r1)
       
  3230 +	ld %r3, RETVAL+0(%r1)
       
  3231  	mtlr %r0
       
  3232 -	addi %r1, %r1, 240
       
  3233 +	addi %r1, %r1, STACKFRAME
       
  3234  	blr
       
  3235  # case FFI_TYPE_SINT64
       
  3236 -	ld %r3, 112+0(%r1)
       
  3237 +	ld %r3, RETVAL+0(%r1)
       
  3238  	mtlr %r0
       
  3239 -	addi %r1, %r1, 240
       
  3240 +	addi %r1, %r1, STACKFRAME
       
  3241  	blr
       
  3242  # case FFI_TYPE_STRUCT
       
  3243  	mtlr %r0
       
  3244 -	addi %r1, %r1, 240
       
  3245 +	addi %r1, %r1, STACKFRAME
       
  3246  	blr
       
  3247  	nop
       
  3248  # case FFI_TYPE_POINTER
       
  3249 -	ld %r3, 112+0(%r1)
       
  3250 +	ld %r3, RETVAL+0(%r1)
       
  3251  	mtlr %r0
       
  3252 -	addi %r1, %r1, 240
       
  3253 +	addi %r1, %r1, STACKFRAME
       
  3254 +	blr
       
  3255 +# case FFI_V2_TYPE_FLOAT_HOMOG
       
  3256 +	lfs %f1, RETVAL+0(%r1)
       
  3257 +	lfs %f2, RETVAL+4(%r1)
       
  3258 +	lfs %f3, RETVAL+8(%r1)
       
  3259 +	b .Lmorefloat
       
  3260 +# case FFI_V2_TYPE_DOUBLE_HOMOG
       
  3261 +	lfd %f1, RETVAL+0(%r1)
       
  3262 +	lfd %f2, RETVAL+8(%r1)
       
  3263 +	lfd %f3, RETVAL+16(%r1)
       
  3264 +	lfd %f4, RETVAL+24(%r1)
       
  3265 +	mtlr %r0
       
  3266 +	lfd %f5, RETVAL+32(%r1)
       
  3267 +	lfd %f6, RETVAL+40(%r1)
       
  3268 +	lfd %f7, RETVAL+48(%r1)
       
  3269 +	lfd %f8, RETVAL+56(%r1)
       
  3270 +	addi %r1, %r1, STACKFRAME
       
  3271 +	blr
       
  3272 +.Lmorefloat:
       
  3273 +	lfs %f4, RETVAL+12(%r1)
       
  3274 +	mtlr %r0
       
  3275 +	lfs %f5, RETVAL+16(%r1)
       
  3276 +	lfs %f6, RETVAL+20(%r1)
       
  3277 +	lfs %f7, RETVAL+24(%r1)
       
  3278 +	lfs %f8, RETVAL+28(%r1)
       
  3279 +	addi %r1, %r1, STACKFRAME
       
  3280 +	blr
       
  3281 +.Lsmall:
       
  3282 +# ifdef __LITTLE_ENDIAN__
       
  3283 +	ld %r3,RETVAL+0(%r1)
       
  3284 +	mtlr %r0
       
  3285 +	ld %r4,RETVAL+8(%r1)
       
  3286 +	addi %r1, %r1, STACKFRAME
       
  3287 +	blr
       
  3288 +# else
       
  3289 +	# A struct smaller than a dword is returned in the low bits of r3
       
  3290 +	# ie. right justified.  Larger structs are passed left justified
       
  3291 +	# in r3 and r4.  The return value area on the stack will have
       
  3292 +	# the structs as they are usually stored in memory.
       
  3293 +	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes?
       
  3294 +	neg %r5, %r3
       
  3295 +	ld %r3,RETVAL+0(%r1)
       
  3296 +	blt .Lsmalldown
       
  3297 +	mtlr %r0
       
  3298 +	ld %r4,RETVAL+8(%r1)
       
  3299 +	addi %r1, %r1, STACKFRAME
       
  3300 +	blr
       
  3301 +.Lsmalldown:
       
  3302 +	addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
       
  3303 +	mtlr %r0
       
  3304 +	sldi %r5, %r5, 3
       
  3305 +	addi %r1, %r1, STACKFRAME
       
  3306 +	srd %r3, %r3, %r5
       
  3307  	blr
       
  3308 -# esac
       
  3309 +# endif
       
  3310 +
       
  3311  .LFE1:
       
  3312  	.long	0
       
  3313  	.byte	0,12,0,1,128,0,0,0
       
  3314 +# if _CALL_ELF == 2
       
  3315 +	.size	ffi_closure_LINUX64,.-ffi_closure_LINUX64
       
  3316 +# else
       
  3317 +#  ifdef _CALL_LINUX
       
  3318 +	.size	ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
       
  3319 +#  else
       
  3320  	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
       
  3321 +#  endif
       
  3322 +# endif
       
  3323  
       
  3324  	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
       
  3325  .Lframe1:
       
  3326 @@ -223,14 +376,14 @@ ffi_closure_LINUX64:
       
  3327  	.byte	0x2	 # DW_CFA_advance_loc1
       
  3328  	.byte	.LCFI0-.LFB1
       
  3329  	.byte	0xe	 # DW_CFA_def_cfa_offset
       
  3330 -	.uleb128 240
       
  3331 +	.uleb128 STACKFRAME
       
  3332  	.byte	0x11	 # DW_CFA_offset_extended_sf
       
  3333  	.uleb128 0x41
       
  3334  	.sleb128 -2
       
  3335  	.align 3
       
  3336  .LEFDE1:
       
  3337 -#endif
       
  3338  
       
  3339 -#if defined __ELF__ && defined __linux__
       
  3340 +# if defined __ELF__ && defined __linux__
       
  3341  	.section	.note.GNU-stack,"",@progbits
       
  3342 +# endif
       
  3343  #endif
       
  3344 --- mozilla/js/src/ctypes/libffi/src/powerpc/linux64.S	2013-10-24 09:56:51.847587813 +0200
       
  3345 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/linux64.S	2013-11-29 17:23:26.000000000 +0100
       
  3346 @@ -30,16 +30,33 @@
       
  3347  #include <ffi.h>
       
  3348  
       
  3349  #ifdef __powerpc64__
       
  3350 -	.hidden	ffi_call_LINUX64, .ffi_call_LINUX64
       
  3351 -	.globl	ffi_call_LINUX64, .ffi_call_LINUX64
       
  3352 +	.hidden	ffi_call_LINUX64
       
  3353 +	.globl	ffi_call_LINUX64
       
  3354 +# if _CALL_ELF == 2
       
  3355 +	.text
       
  3356 +ffi_call_LINUX64:
       
  3357 +	addis	%r2, %r12, .TOC.-ffi_call_LINUX64@ha
       
  3358 +	addi	%r2, %r2, .TOC.-ffi_call_LINUX64@l
       
  3359 +	.localentry ffi_call_LINUX64, . - ffi_call_LINUX64
       
  3360 +# else
       
  3361  	.section	".opd","aw"
       
  3362  	.align	3
       
  3363  ffi_call_LINUX64:
       
  3364 +#  ifdef _CALL_LINUX
       
  3365 +	.quad	.L.ffi_call_LINUX64,.TOC.@tocbase,0
       
  3366 +	.type	ffi_call_LINUX64,@function
       
  3367 +	.text
       
  3368 +.L.ffi_call_LINUX64:
       
  3369 +#  else
       
  3370 +	.hidden	.ffi_call_LINUX64
       
  3371 +	.globl	.ffi_call_LINUX64
       
  3372  	.quad	.ffi_call_LINUX64,.TOC.@tocbase,0
       
  3373  	.size	ffi_call_LINUX64,24
       
  3374  	.type	.ffi_call_LINUX64,@function
       
  3375  	.text
       
  3376  .ffi_call_LINUX64:
       
  3377 +#  endif
       
  3378 +# endif
       
  3379  .LFB1:
       
  3380  	mflr	%r0
       
  3381  	std	%r28, -32(%r1)
       
  3382 @@ -54,22 +71,35 @@ ffi_call_LINUX64:
       
  3383  	mr	%r31, %r5	/* flags, */
       
  3384  	mr	%r30, %r6	/* rvalue, */
       
  3385  	mr	%r29, %r7	/* function address.  */
       
  3386 +/* Save toc pointer, not for the ffi_prep_args64 call, but for the later
       
  3387 +   bctrl function call.  */
       
  3388 +# if _CALL_ELF == 2
       
  3389 +	std	%r2, 24(%r1)
       
  3390 +# else
       
  3391  	std	%r2, 40(%r1)
       
  3392 +# endif
       
  3393  
       
  3394  	/* Call ffi_prep_args64.  */
       
  3395  	mr	%r4, %r1
       
  3396 +# if defined _CALL_LINUX || _CALL_ELF == 2
       
  3397 +	bl	ffi_prep_args64
       
  3398 +# else
       
  3399  	bl	.ffi_prep_args64
       
  3400 +# endif
       
  3401  
       
  3402 -	ld	%r0, 0(%r29)
       
  3403 +# if _CALL_ELF == 2
       
  3404 +	mr	%r12, %r29
       
  3405 +# else
       
  3406 +	ld	%r12, 0(%r29)
       
  3407  	ld	%r2, 8(%r29)
       
  3408  	ld	%r11, 16(%r29)
       
  3409 -
       
  3410 +# endif
       
  3411  	/* Now do the call.  */
       
  3412  	/* Set up cr1 with bits 4-7 of the flags.  */
       
  3413  	mtcrf	0x40, %r31
       
  3414  
       
  3415  	/* Get the address to call into CTR.  */
       
  3416 -	mtctr	%r0
       
  3417 +	mtctr	%r12
       
  3418  	/* Load all those argument registers.  */
       
  3419  	ld	%r3, -32-(8*8)(%r28)
       
  3420  	ld	%r4, -32-(7*8)(%r28)
       
  3421 @@ -104,12 +134,17 @@ ffi_call_LINUX64:
       
  3422  
       
  3423  	/* This must follow the call immediately, the unwinder
       
  3424  	   uses this to find out if r2 has been saved or not.  */
       
  3425 +# if _CALL_ELF == 2
       
  3426 +	ld	%r2, 24(%r1)
       
  3427 +# else
       
  3428  	ld	%r2, 40(%r1)
       
  3429 +# endif
       
  3430  
       
  3431  	/* Now, deal with the return value.  */
       
  3432  	mtcrf	0x01, %r31
       
  3433 -	bt-	30, .Ldone_return_value
       
  3434 -	bt-	29, .Lfp_return_value
       
  3435 +	bt	31, .Lstruct_return_value
       
  3436 +	bt	30, .Ldone_return_value
       
  3437 +	bt	29, .Lfp_return_value
       
  3438  	std	%r3, 0(%r30)
       
  3439  	/* Fall through...  */
       
  3440  
       
  3441 @@ -117,7 +152,7 @@ ffi_call_LINUX64:
       
  3442  	/* Restore the registers we used and return.  */
       
  3443  	mr	%r1, %r28
       
  3444  	ld	%r0, 16(%r28)
       
  3445 -	ld	%r28, -32(%r1)
       
  3446 +	ld	%r28, -32(%r28)
       
  3447  	mtlr	%r0
       
  3448  	ld	%r29, -24(%r1)
       
  3449  	ld	%r30, -16(%r1)
       
  3450 @@ -134,10 +169,48 @@ ffi_call_LINUX64:
       
  3451  .Lfloat_return_value:
       
  3452  	stfs	%f1, 0(%r30)
       
  3453  	b	.Ldone_return_value
       
  3454 +
       
  3455 +.Lstruct_return_value:
       
  3456 +	bf	29, .Lsmall_struct
       
  3457 +	bf	28, .Lfloat_homog_return_value
       
  3458 +	stfd	%f1, 0(%r30)
       
  3459 +	stfd	%f2, 8(%r30)
       
  3460 +	stfd	%f3, 16(%r30)
       
  3461 +	stfd	%f4, 24(%r30)
       
  3462 +	stfd	%f5, 32(%r30)
       
  3463 +	stfd	%f6, 40(%r30)
       
  3464 +	stfd	%f7, 48(%r30)
       
  3465 +	stfd	%f8, 56(%r30)
       
  3466 +	b	.Ldone_return_value
       
  3467 +
       
  3468 +.Lfloat_homog_return_value:
       
  3469 +	stfs	%f1, 0(%r30)
       
  3470 +	stfs	%f2, 4(%r30)
       
  3471 +	stfs	%f3, 8(%r30)
       
  3472 +	stfs	%f4, 12(%r30)
       
  3473 +	stfs	%f5, 16(%r30)
       
  3474 +	stfs	%f6, 20(%r30)
       
  3475 +	stfs	%f7, 24(%r30)
       
  3476 +	stfs	%f8, 28(%r30)
       
  3477 +	b	.Ldone_return_value
       
  3478 +
       
  3479 +.Lsmall_struct:
       
  3480 +	std	%r3, 0(%r30)
       
  3481 +	std	%r4, 8(%r30)
       
  3482 +	b	.Ldone_return_value
       
  3483 +
       
  3484  .LFE1:
       
  3485  	.long	0
       
  3486  	.byte	0,12,0,1,128,4,0,0
       
  3487 +# if _CALL_ELF == 2
       
  3488 +	.size	ffi_call_LINUX64,.-ffi_call_LINUX64
       
  3489 +# else
       
  3490 +#  ifdef _CALL_LINUX
       
  3491 +	.size	ffi_call_LINUX64,.-.L.ffi_call_LINUX64
       
  3492 +#  else
       
  3493  	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64
       
  3494 +#  endif
       
  3495 +# endif
       
  3496  
       
  3497  	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
       
  3498  .Lframe1:
       
  3499 @@ -180,8 +253,8 @@ ffi_call_LINUX64:
       
  3500  	.uleb128 0x4
       
  3501  	.align 3
       
  3502  .LEFDE1:
       
  3503 -#endif
       
  3504  
       
  3505 -#if defined __ELF__ && defined __linux__
       
  3506 +# if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
       
  3507  	.section	.note.GNU-stack,"",@progbits
       
  3508 +# endif
       
  3509  #endif
       
  3510 --- mozilla/js/src/ctypes/libffi/src/powerpc/ppc_closure.S	2013-10-24 09:56:51.847587813 +0200
       
  3511 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/ppc_closure.S	2013-11-29 17:23:26.000000000 +0100
       
  3512 @@ -122,43 +122,78 @@ ENTRY(ffi_closure_SYSV)
       
  3513  	blr
       
  3514  
       
  3515  # case FFI_TYPE_FLOAT
       
  3516 +#ifndef __NO_FPRS__
       
  3517  	lfs %f1,112+0(%r1)
       
  3518  	mtlr %r0
       
  3519  	addi %r1,%r1,144
       
  3520 +#else
       
  3521 +	nop
       
  3522 +	nop
       
  3523 +	nop
       
  3524 +#endif
       
  3525  	blr
       
  3526  
       
  3527  # case FFI_TYPE_DOUBLE
       
  3528 +#ifndef __NO_FPRS__
       
  3529  	lfd %f1,112+0(%r1)
       
  3530  	mtlr %r0
       
  3531  	addi %r1,%r1,144
       
  3532 +#else
       
  3533 +	nop
       
  3534 +	nop
       
  3535 +	nop
       
  3536 +#endif
       
  3537  	blr
       
  3538  
       
  3539  # case FFI_TYPE_LONGDOUBLE
       
  3540 +#ifndef __NO_FPRS__
       
  3541  	lfd %f1,112+0(%r1)
       
  3542  	lfd %f2,112+8(%r1)
       
  3543  	mtlr %r0
       
  3544  	b .Lfinish
       
  3545 +#else
       
  3546 +	nop
       
  3547 +	nop
       
  3548 +	nop
       
  3549 +	blr
       
  3550 +#endif
       
  3551  
       
  3552  # case FFI_TYPE_UINT8
       
  3553 +#ifdef __LITTLE_ENDIAN__
       
  3554 +	lbz %r3,112+0(%r1)
       
  3555 +#else
       
  3556  	lbz %r3,112+3(%r1)
       
  3557 +#endif
       
  3558  	mtlr %r0
       
  3559  	addi %r1,%r1,144
       
  3560  	blr
       
  3561  
       
  3562  # case FFI_TYPE_SINT8
       
  3563 +#ifdef __LITTLE_ENDIAN__
       
  3564 +	lbz %r3,112+0(%r1)
       
  3565 +#else
       
  3566  	lbz %r3,112+3(%r1)
       
  3567 +#endif
       
  3568  	extsb %r3,%r3
       
  3569  	mtlr %r0
       
  3570  	b .Lfinish
       
  3571  
       
  3572  # case FFI_TYPE_UINT16
       
  3573 +#ifdef __LITTLE_ENDIAN__
       
  3574 +	lhz %r3,112+0(%r1)
       
  3575 +#else
       
  3576  	lhz %r3,112+2(%r1)
       
  3577 +#endif
       
  3578  	mtlr %r0
       
  3579  	addi %r1,%r1,144
       
  3580  	blr
       
  3581  
       
  3582  # case FFI_TYPE_SINT16
       
  3583 +#ifdef __LITTLE_ENDIAN__
       
  3584 +	lha %r3,112+0(%r1)
       
  3585 +#else
       
  3586  	lha %r3,112+2(%r1)
       
  3587 +#endif
       
  3588  	mtlr %r0
       
  3589  	addi %r1,%r1,144
       
  3590  	blr
       
  3591 @@ -203,7 +238,7 @@ ENTRY(ffi_closure_SYSV)
       
  3592  	lwz %r3,112+0(%r1)
       
  3593  	lwz %r4,112+4(%r1)
       
  3594  	lwz %r5,112+8(%r1)
       
  3595 -	bl .Luint128
       
  3596 +	b .Luint128
       
  3597  
       
  3598  # The return types below are only used when the ABI type is FFI_SYSV.
       
  3599  # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
       
  3600 @@ -220,9 +255,15 @@ ENTRY(ffi_closure_SYSV)
       
  3601  
       
  3602  # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
       
  3603  	lwz %r3,112+0(%r1)
       
  3604 +#ifdef __LITTLE_ENDIAN__
       
  3605 +	mtlr %r0
       
  3606 +	addi %r1,%r1,144
       
  3607 +	blr
       
  3608 +#else
       
  3609  	srwi %r3,%r3,8
       
  3610  	mtlr %r0
       
  3611  	b .Lfinish
       
  3612 +#endif
       
  3613  
       
  3614  # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
       
  3615  	lwz %r3,112+0(%r1)
       
  3616 @@ -233,20 +274,35 @@ ENTRY(ffi_closure_SYSV)
       
  3617  # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
       
  3618  	lwz %r3,112+0(%r1)
       
  3619  	lwz %r4,112+4(%r1)
       
  3620 +#ifdef __LITTLE_ENDIAN__
       
  3621 +	mtlr %r0
       
  3622 +	b .Lfinish
       
  3623 +#else
       
  3624  	li %r5,24
       
  3625  	b .Lstruct567
       
  3626 +#endif
       
  3627  
       
  3628  # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
       
  3629  	lwz %r3,112+0(%r1)
       
  3630  	lwz %r4,112+4(%r1)
       
  3631 +#ifdef __LITTLE_ENDIAN__
       
  3632 +	mtlr %r0
       
  3633 +	b .Lfinish
       
  3634 +#else
       
  3635  	li %r5,16
       
  3636  	b .Lstruct567
       
  3637 +#endif
       
  3638  
       
  3639  # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
       
  3640  	lwz %r3,112+0(%r1)
       
  3641  	lwz %r4,112+4(%r1)
       
  3642 +#ifdef __LITTLE_ENDIAN__
       
  3643 +	mtlr %r0
       
  3644 +	b .Lfinish
       
  3645 +#else
       
  3646  	li %r5,8
       
  3647  	b .Lstruct567
       
  3648 +#endif
       
  3649  
       
  3650  # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
       
  3651  	lwz %r3,112+0(%r1)
       
  3652 @@ -254,6 +310,7 @@ ENTRY(ffi_closure_SYSV)
       
  3653  	mtlr %r0
       
  3654  	b .Lfinish
       
  3655  
       
  3656 +#ifndef __LITTLE_ENDIAN__
       
  3657  .Lstruct567:
       
  3658  	subfic %r6,%r5,32
       
  3659  	srw %r4,%r4,%r5
       
  3660 @@ -263,6 +320,7 @@ ENTRY(ffi_closure_SYSV)
       
  3661  	mtlr %r0
       
  3662  	addi %r1,%r1,144
       
  3663  	blr
       
  3664 +#endif
       
  3665  
       
  3666  .Luint128:
       
  3667  	lwz %r6,112+12(%r1)
       
  3668 --- mozilla/js/src/ctypes/libffi/src/powerpc/sysv.S	2013-10-24 09:56:51.848587813 +0200
       
  3669 +++ /suse/dvaleev/obs/openSUSE:Factory:PowerLE/libffi48/gcc-4.8-ibmr205465/libffi/src/powerpc/sysv.S	2013-11-29 17:23:26.000000000 +0100
       
  3670 @@ -83,6 +83,7 @@ ENTRY(ffi_call_SYSV)
       
  3671  	nop
       
  3672  1:
       
  3673  
       
  3674 +#ifndef __NO_FPRS__
       
  3675  	/* Load all the FP registers.  */
       
  3676  	bf-	6,2f
       
  3677  	lfd	%f1,-16-(8*4)-(8*8)(%r28)
       
  3678 @@ -94,6 +95,7 @@ ENTRY(ffi_call_SYSV)
       
  3679  	lfd	%f6,-16-(8*4)-(3*8)(%r28)
       
  3680  	lfd	%f7,-16-(8*4)-(2*8)(%r28)
       
  3681  	lfd	%f8,-16-(8*4)-(1*8)(%r28)
       
  3682 +#endif
       
  3683  2:
       
  3684  
       
  3685  	/* Make the call.  */
       
  3686 @@ -103,7 +105,9 @@ ENTRY(ffi_call_SYSV)
       
  3687  	mtcrf	0x01,%r31 /* cr7  */
       
  3688  	bt-	31,L(small_struct_return_value)
       
  3689  	bt-	30,L(done_return_value)
       
  3690 +#ifndef __NO_FPRS__
       
  3691  	bt-	29,L(fp_return_value)
       
  3692 +#endif
       
  3693  	stw	%r3,0(%r30)
       
  3694  	bf+	28,L(done_return_value)
       
  3695  	stw	%r4,4(%r30)
       
  3696 @@ -124,6 +128,7 @@ L(done_return_value):
       
  3697  	lwz	%r1,0(%r1)
       
  3698  	blr
       
  3699  
       
  3700 +#ifndef __NO_FPRS__
       
  3701  L(fp_return_value):
       
  3702  	bf	28,L(float_return_value)
       
  3703  	stfd	%f1,0(%r30)
       
  3704 @@ -134,21 +139,17 @@ L(fp_return_value):
       
  3705  L(float_return_value):
       
  3706  	stfs	%f1,0(%r30)
       
  3707  	b	L(done_return_value)
       
  3708 +#endif
       
  3709  
       
  3710  L(small_struct_return_value):
       
  3711 -	extrwi	%r6,%r31,2,19         /* number of bytes padding = shift/8 */
       
  3712 -	mtcrf	0x02,%r31	      /* copy flags to cr[24:27] (cr6) */
       
  3713 -	extrwi	%r5,%r31,5,19         /* r5 <- number of bits of padding */
       
  3714 -	subfic  %r6,%r6,4             /* r6 <- number of useful bytes in r3 */
       
  3715 -	bf-	25,L(done_return_value) /* struct in r3 ? if not, done. */
       
  3716 -/* smst_one_register: */
       
  3717 -	slw	%r3,%r3,%r5           /* Left-justify value in r3 */
       
  3718 -	mtxer	%r6                   /* move byte count to XER ... */
       
  3719 -	stswx	%r3,0,%r30            /* ... and store that many bytes */
       
  3720 -	bf+	26,L(done_return_value)  /* struct in r3:r4 ? */
       
  3721 -	add	%r6,%r6,%r30          /* adjust pointer */
       
  3722 -	stswi	%r4,%r6,4             /* store last four bytes */
       
  3723 -	b	L(done_return_value)
       
  3724 +	/*
       
  3725 +	 * The C code always allocates a properly-aligned 8-byte bounce
       
  3726 +	 * buffer to make this assembly code very simple.  Just write out
       
  3727 +	 * r3 and r4 to the buffer to allow the C code to handle the rest.
       
  3728 +	 */
       
  3729 +	stw %r3, 0(%r30)
       
  3730 +	stw %r4, 4(%r30)
       
  3731 +	b L(done_return_value)
       
  3732  
       
  3733  .LFE1:
       
  3734  END(ffi_call_SYSV)