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