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