update of PPC64LE patches taken from
authorWolfgang Rosenauer <wr@rosenauer.org>
Sun, 16 Mar 2014 10:38:59 +0100
changeset 710 5341dc98d26c
parent 709 7ce157f366c9
child 711 012a5adf5c74
update of PPC64LE patches taken from https://build.opensuse.org/request/show/224301
MozillaFirefox/MozillaFirefox.changes
MozillaFirefox/MozillaFirefox.spec
MozillaFirefox/mozilla-libffi-ppc64le.patch
MozillaFirefox/mozilla-ppc64le-build.patch
MozillaFirefox/mozilla-ppc64le-javascript.patch
MozillaFirefox/mozilla-ppc64le-libffi.patch
MozillaFirefox/mozilla-ppc64le-mfbt.patch
MozillaFirefox/mozilla-ppc64le-webrtc.patch
MozillaFirefox/mozilla-ppc64le-xpcom.patch
MozillaFirefox/mozilla-ppc64le.patch
MozillaFirefox/mozilla-xpcom-ppc64le.patch
mozilla-libffi-ppc64le.patch
mozilla-ppc64le-build.patch
mozilla-ppc64le-javascript.patch
mozilla-ppc64le-libffi.patch
mozilla-ppc64le-mfbt.patch
mozilla-ppc64le-webrtc.patch
mozilla-ppc64le-xpcom.patch
mozilla-ppc64le.patch
mozilla-xpcom-ppc64le.patch
series
--- a/MozillaFirefox/MozillaFirefox.changes	Sun Mar 16 09:27:07 2014 +0100
+++ b/MozillaFirefox/MozillaFirefox.changes	Sun Mar 16 10:38:59 2014 +0100
@@ -5,6 +5,7 @@
 - requires NSPR 4.10.3 and NSS 3.15.5
 - new build dependency:
   * libpulse
+- update of PowerPC 64 patches (bmo#976648) (pcerny@suse.com)
 
 -------------------------------------------------------------------
 Mon Feb 17 11:59:28 UTC 2014 - wr@rosenauer.org
--- a/MozillaFirefox/MozillaFirefox.spec	Sun Mar 16 09:27:07 2014 +0100
+++ b/MozillaFirefox/MozillaFirefox.spec	Sun Mar 16 10:38:59 2014 +0100
@@ -106,9 +106,12 @@
 Patch12:        mozilla-arm-disable-edsp.patch
 Patch13:        mozilla-ppc.patch
 Patch14:        mozilla-libproxy-compat.patch
-Patch15:        mozilla-ppc64le.patch
-Patch16:        mozilla-libffi-ppc64le.patch
-Patch17:        mozilla-xpcom-ppc64le.patch
+Patch15:        mozilla-ppc64le-build.patch
+Patch16:        mozilla-ppc64le-javascript.patch
+Patch17:        mozilla-ppc64le-libffi.patch
+Patch18:        mozilla-ppc64le-mfbt.patch
+Patch19:        mozilla-ppc64le-webrtc.patch
+Patch20:        mozilla-ppc64le-xpcom.patch
 # Firefox/browser
 Patch30:        firefox-browser-css.patch
 Patch31:        firefox-kde.patch
@@ -251,6 +254,9 @@
 %patch15 -p1
 %patch16 -p1
 %patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
 #
 %patch30 -p1
 %patch31 -p1
--- a/MozillaFirefox/mozilla-libffi-ppc64le.patch	Sun Mar 16 09:27:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../mozilla-libffi-ppc64le.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-ppc64le-build.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,1 @@
+../mozilla-ppc64le-build.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-ppc64le-javascript.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,1 @@
+../mozilla-ppc64le-javascript.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-ppc64le-libffi.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,1 @@
+../mozilla-ppc64le-libffi.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-ppc64le-mfbt.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,1 @@
+../mozilla-ppc64le-mfbt.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-ppc64le-webrtc.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,1 @@
+../mozilla-ppc64le-webrtc.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-ppc64le-xpcom.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,1 @@
+../mozilla-ppc64le-xpcom.patch
\ No newline at end of file
--- a/MozillaFirefox/mozilla-ppc64le.patch	Sun Mar 16 09:27:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../mozilla-ppc64le.patch
\ No newline at end of file
--- a/MozillaFirefox/mozilla-xpcom-ppc64le.patch	Sun Mar 16 09:27:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-../mozilla-xpcom-ppc64le.patch
\ No newline at end of file
--- a/mozilla-libffi-ppc64le.patch	Sun Mar 16 09:27:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4441 +0,0 @@
-# HG changeset patch
-# Parent a38c083288a664a9b1fdeaa16563b47661ef6c16
-# User Ulrich Weigand <uweigand@de.ibm.com>
-PPC64 LE support for libffi
-
-diff --git a/js/src/ctypes/libffi/src/powerpc/aix.S b/js/src/ctypes/libffi/src/powerpc/aix.S
---- a/js/src/ctypes/libffi/src/powerpc/aix.S
-+++ b/js/src/ctypes/libffi/src/powerpc/aix.S
-@@ -1,10 +1,10 @@
- /* -----------------------------------------------------------------------
--   aix.S - Copyright (c) 2002,2009 Free Software Foundation, Inc.
-+   aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc.
-    based on darwin.S by John Hornkvist
- 
-    PowerPC Assembly glue.
- 
-    Permission is hereby granted, free of charge, to any person obtaining
-    a copy of this software and associated documentation files (the
-    ``Software''), to deal in the Software without restriction, including
-    without limitation the rights to use, copy, modify, merge, publish,
-@@ -74,16 +74,18 @@
- 	.set f15,15
- 	.set f16,16
- 	.set f17,17
- 	.set f18,18
- 	.set f19,19
- 	.set f20,20
- 	.set f21,21
- 
-+	.extern .ffi_prep_args
-+
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #define JUMPTARGET(name) name
- #define L(x) x
- 	.file "aix.S"
- 	.toc
- 
-@@ -120,16 +122,17 @@ ffi_call_AIX:
- 	mr	r31, r5	/* flags, */
- 	mr	r30, r6	/* rvalue, */
- 	mr	r29, r7	/* function address.  */
- 	std	r2, 40(r1)
- 
- 	/* Call ffi_prep_args.  */
- 	mr	r4, r1
- 	bl	.ffi_prep_args
-+	nop
- 
- 	/* Now do the call.  */
- 	ld	r0, 0(r29)
- 	ld	r2, 8(r29)
- 	ld	r11, 16(r29)
- 	/* Set up cr1 with bits 4-7 of the flags.  */
- 	mtcrf	0x40, r31
- 	mtctr	r0
-@@ -221,16 +224,17 @@ L(float_return_value):
- 	mr	r31, r5	/* flags, */
- 	mr	r30, r6	/* rvalue, */
- 	mr	r29, r7	/* function address, */
- 	stw	r2, 20(r1)
- 
- 	/* Call ffi_prep_args.  */
- 	mr	r4, r1
- 	bl	.ffi_prep_args
-+	nop
- 
- 	/* Now do the call.  */
- 	lwz	r0, 0(r29)
- 	lwz	r2, 4(r29)
- 	lwz	r11, 8(r29)
- 	/* Set up cr1 with bits 4-7 of the flags.  */
- 	mtcrf	0x40, r31
- 	mtctr	r0
-diff --git a/js/src/ctypes/libffi/src/powerpc/ffi.c b/js/src/ctypes/libffi/src/powerpc/ffi.c
---- a/js/src/ctypes/libffi/src/powerpc/ffi.c
-+++ b/js/src/ctypes/libffi/src/powerpc/ffi.c
-@@ -1,12 +1,14 @@
- /* -----------------------------------------------------------------------
--   ffi.c - Copyright (c) 1998 Geoffrey Keating
--   Copyright (C) 2007, 2008 Free Software Foundation, Inc
--   Copyright (C) 2008 Red Hat, Inc
-+   ffi.c - Copyright (C) 2011 Anthony Green
-+           Copyright (C) 2011 Kyle Moffett
-+           Copyright (C) 2008 Red Hat, Inc
-+           Copyright (C) 2007, 2008 Free Software Foundation, Inc
-+	   Copyright (c) 1998 Geoffrey Keating
- 
-    PowerPC Foreign Function Interface
- 
-    Permission is hereby granted, free of charge, to any person obtaining
-    a copy of this software and associated documentation files (the
-    ``Software''), to deal in the Software without restriction, including
-    without limitation the rights to use, copy, modify, merge, publish,
-    distribute, sublicense, and/or sell copies of the Software, and to
-@@ -34,42 +36,39 @@
- 
- extern void ffi_closure_SYSV (void);
- extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
- 
- enum {
-   /* The assembly depends on these exact flags.  */
-   FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
-   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
-+#ifndef __NO_FPRS__
-   FLAG_RETURNS_FP       = 1 << (31-29),
-+#endif
-   FLAG_RETURNS_64BITS   = 1 << (31-28),
- 
-   FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
--  FLAG_SYSV_SMST_R4     = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
--					   structs.  */
--  FLAG_SYSV_SMST_R3     = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
--					   structs.  */
--  /* Bits (31-24) through (31-19) store shift value for SMST */
- 
-   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
-+  FLAG_ARG_NEEDS_PSAVE  = FLAG_ARG_NEEDS_COPY, /* Used by ELFv2 */
-+#ifndef __NO_FPRS__
-   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
-+#endif
-   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
-   FLAG_RETVAL_REFERENCE = 1 << (31- 4)
- };
- 
- /* About the SYSV ABI.  */
--unsigned int NUM_GPR_ARG_REGISTERS = 8;
-+#define ASM_NEEDS_REGISTERS 4
-+#define NUM_GPR_ARG_REGISTERS 8
- #ifndef __NO_FPRS__
--unsigned int NUM_FPR_ARG_REGISTERS = 8;
--#else
--unsigned int NUM_FPR_ARG_REGISTERS = 0;
-+# define NUM_FPR_ARG_REGISTERS 8
- #endif
- 
--enum { ASM_NEEDS_REGISTERS = 4 };
--
- /* ffi_prep_args_SYSV is called by the assembly routine once stack space
-    has been allocated for the function's arguments.
- 
-    The stack layout we want looks like this:
- 
-    |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
-    |--------------------------------------------|
-    |   Previous backchain pointer	4	|       stack pointer here
-@@ -108,100 +107,119 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
-   /* 'stacktop' points at the previous backchain pointer.  */
-   valp stacktop;
- 
-   /* 'gpr_base' points at the space for gpr3, and grows upwards as
-      we use GPR registers.  */
-   valp gpr_base;
-   int intarg_count;
- 
-+#ifndef __NO_FPRS__
-   /* 'fpr_base' points at the space for fpr1, and grows upwards as
-      we use FPR registers.  */
-   valp fpr_base;
-   int fparg_count;
-+#endif
- 
-   /* 'copy_space' grows down as we put structures in it.  It should
-      stay 16-byte aligned.  */
-   valp copy_space;
- 
-   /* 'next_arg' grows up as we put parameters in it.  */
-   valp next_arg;
- 
--  int i, ii MAYBE_UNUSED;
-+  int i;
-   ffi_type **ptr;
-+#ifndef __NO_FPRS__
-   double double_tmp;
-+#endif
-   union {
-     void **v;
-     char **c;
-     signed char **sc;
-     unsigned char **uc;
-     signed short **ss;
-     unsigned short **us;
-     unsigned int **ui;
-     long long **ll;
-     float **f;
-     double **d;
-   } p_argv;
-   size_t struct_copy_size;
-   unsigned gprvalue;
- 
--  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
--    NUM_FPR_ARG_REGISTERS = 0;
--
-   stacktop.c = (char *) stack + bytes;
-   gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
-   intarg_count = 0;
-+#ifndef __NO_FPRS__
-   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
-   fparg_count = 0;
-   copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
-+#else
-+  copy_space.c = gpr_base.c;
-+#endif
-   next_arg.u = stack + 2;
- 
-   /* Check that everything starts aligned properly.  */
--  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
--  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
--  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
-+  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
-+  FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
-+  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
-   FFI_ASSERT ((bytes & 0xF) == 0);
-   FFI_ASSERT (copy_space.c >= next_arg.c);
- 
-   /* Deal with return values that are actually pass-by-reference.  */
-   if (flags & FLAG_RETVAL_REFERENCE)
-     {
-       *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
-       intarg_count++;
-     }
- 
-   /* Now for the arguments.  */
-   p_argv.v = ecif->avalue;
-   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
-        i > 0;
-        i--, ptr++, p_argv.v++)
-     {
--      switch ((*ptr)->type)
--	{
-+      unsigned short typenum = (*ptr)->type;
-+
-+      /* We may need to handle some values depending on ABI */
-+      if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) {
-+		if (typenum == FFI_TYPE_FLOAT)
-+			typenum = FFI_TYPE_UINT32;
-+		if (typenum == FFI_TYPE_DOUBLE)
-+			typenum = FFI_TYPE_UINT64;
-+		if (typenum == FFI_TYPE_LONGDOUBLE)
-+			typenum = FFI_TYPE_UINT128;
-+      } else if (ecif->cif->abi != FFI_LINUX) {
-+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-+		if (typenum == FFI_TYPE_LONGDOUBLE)
-+			typenum = FFI_TYPE_STRUCT;
-+#endif
-+      }
-+
-+      /* Now test the translated value */
-+      switch (typenum) {
-+#ifndef __NO_FPRS__
- 	case FFI_TYPE_FLOAT:
- 	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
--	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
--	    goto soft_float_prep;
- 	  double_tmp = **p_argv.f;
- 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
- 	    {
- 	      *next_arg.f = (float) double_tmp;
- 	      next_arg.u += 1;
- 	      intarg_count++;
- 	    }
- 	  else
- 	    *fpr_base.d++ = double_tmp;
- 	  fparg_count++;
- 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
- 	  break;
- 
- 	case FFI_TYPE_DOUBLE:
- 	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
--	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
--	    goto soft_double_prep;
- 	  double_tmp = **p_argv.d;
- 
- 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
- 	    {
- 	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
- 		  && intarg_count % 2 != 0)
- 		{
- 		  intarg_count++;
-@@ -213,53 +231,16 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
- 	  else
- 	    *fpr_base.d++ = double_tmp;
- 	  fparg_count++;
- 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
- 	  break;
- 
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- 	case FFI_TYPE_LONGDOUBLE:
--	  if ((ecif->cif->abi != FFI_LINUX)
--		&& (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
--	    goto do_struct;
--	  /* The soft float ABI for long doubles works like this,
--	     a long double is passed in four consecutive gprs if available.
--	     A maximum of 2 long doubles can be passed in gprs.
--	     If we do not have 4 gprs left, the long double is passed on the
--	     stack, 4-byte aligned.  */
--	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
--	    {
--	      unsigned int int_tmp = (*p_argv.ui)[0];
--	      if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
--		{
--		  if (intarg_count < NUM_GPR_ARG_REGISTERS)
--		    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
--		  *next_arg.u = int_tmp;
--		  next_arg.u++;
--		  for (ii = 1; ii < 4; ii++)
--		    {
--		      int_tmp = (*p_argv.ui)[ii];
--		      *next_arg.u = int_tmp;
--		      next_arg.u++;
--		    }
--		}
--	      else
--		{
--		  *gpr_base.u++ = int_tmp;
--		  for (ii = 1; ii < 4; ii++)
--		    {
--		      int_tmp = (*p_argv.ui)[ii];
--		      *gpr_base.u++ = int_tmp;
--		    }
--		}
--	      intarg_count +=4;
--	    }
--	  else
--	    {
- 	      double_tmp = (*p_argv.d)[0];
- 
- 	      if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
- 		{
- 		  if (intarg_count >= NUM_GPR_ARG_REGISTERS
- 		      && intarg_count % 2 != 0)
- 		    {
- 		      intarg_count++;
-@@ -275,23 +256,50 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
- 		{
- 		  *fpr_base.d++ = double_tmp;
- 		  double_tmp = (*p_argv.d)[1];
- 		  *fpr_base.d++ = double_tmp;
- 		}
- 
- 	      fparg_count += 2;
- 	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
--	    }
- 	  break;
- #endif
-+#endif /* have FPRs */
-+
-+	/*
-+	 * The soft float ABI for long doubles works like this, a long double
-+	 * is passed in four consecutive GPRs if available.  A maximum of 2
-+	 * long doubles can be passed in gprs.  If we do not have 4 GPRs
-+	 * left, the long double is passed on the stack, 4-byte aligned.
-+	 */
-+	case FFI_TYPE_UINT128: {
-+		unsigned int int_tmp = (*p_argv.ui)[0];
-+		unsigned int ii;
-+		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) {
-+			if (intarg_count < NUM_GPR_ARG_REGISTERS)
-+				intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
-+			*(next_arg.u++) = int_tmp;
-+			for (ii = 1; ii < 4; ii++) {
-+				int_tmp = (*p_argv.ui)[ii];
-+				*(next_arg.u++) = int_tmp;
-+			}
-+		} else {
-+			*(gpr_base.u++) = int_tmp;
-+			for (ii = 1; ii < 4; ii++) {
-+				int_tmp = (*p_argv.ui)[ii];
-+				*(gpr_base.u++) = int_tmp;
-+			}
-+		}
-+		intarg_count += 4;
-+		break;
-+	}
- 
- 	case FFI_TYPE_UINT64:
- 	case FFI_TYPE_SINT64:
--	soft_double_prep:
- 	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
- 	    intarg_count++;
- 	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
- 	    {
- 	      if (intarg_count % 2 != 0)
- 		{
- 		  intarg_count++;
- 		  next_arg.u++;
-@@ -314,19 +322,16 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
- 		  gpr_base.u++;
- 		}
- 	      *gpr_base.ll++ = **p_argv.ll;
- 	    }
- 	  intarg_count += 2;
- 	  break;
- 
- 	case FFI_TYPE_STRUCT:
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--	do_struct:
--#endif
- 	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
- 	  copy_space.c -= struct_copy_size;
- 	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
- 
- 	  gprvalue = (unsigned long) copy_space.c;
- 
- 	  FFI_ASSERT (copy_space.c > next_arg.c);
- 	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
-@@ -344,45 +349,91 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
- 	case FFI_TYPE_SINT16:
- 	  gprvalue = **p_argv.ss;
- 	  goto putgpr;
- 
- 	case FFI_TYPE_INT:
- 	case FFI_TYPE_UINT32:
- 	case FFI_TYPE_SINT32:
- 	case FFI_TYPE_POINTER:
--	soft_float_prep:
- 
- 	  gprvalue = **p_argv.ui;
- 
- 	putgpr:
- 	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
- 	    *next_arg.u++ = gprvalue;
- 	  else
- 	    *gpr_base.u++ = gprvalue;
- 	  intarg_count++;
- 	  break;
- 	}
-     }
- 
-   /* Check that we didn't overrun the stack...  */
-   FFI_ASSERT (copy_space.c >= next_arg.c);
-   FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
-+  /* The assert below is testing that the number of integer arguments agrees
-+     with the number found in ffi_prep_cif_machdep().  However, intarg_count
-+     is incremented whenever we place an FP arg on the stack, so account for
-+     that before our assert test.  */
-+#ifndef __NO_FPRS__
-+  if (fparg_count > NUM_FPR_ARG_REGISTERS)
-+    intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS;
-   FFI_ASSERT (fpr_base.u
- 	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
-+#endif
-   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
- }
- 
- /* About the LINUX64 ABI.  */
- enum {
-   NUM_GPR_ARG_REGISTERS64 = 8,
-   NUM_FPR_ARG_REGISTERS64 = 13
- };
- enum { ASM_NEEDS_REGISTERS64 = 4 };
- 
-+#if _CALL_ELF == 2
-+static unsigned int
-+discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
-+{
-+  switch (t->type)
-+    {
-+    case FFI_TYPE_FLOAT:
-+    case FFI_TYPE_DOUBLE:
-+      *elnum = 1;
-+      return (int) t->type;
-+
-+    case FFI_TYPE_STRUCT:;
-+      {
-+	unsigned int base_elt = 0, total_elnum = 0;
-+	ffi_type **el = t->elements;
-+	while (*el)
-+	  {
-+	    unsigned int el_elt, el_elnum = 0;
-+	    el_elt = discover_homogeneous_aggregate (*el, &el_elnum);
-+	    if (el_elt == 0
-+		|| (base_elt && base_elt != el_elt))
-+	      return 0;
-+	    base_elt = el_elt;
-+	    total_elnum += el_elnum;
-+	    if (total_elnum > 8)
-+	      return 0;
-+	    el++;
-+	  }
-+	*elnum = total_elnum;
-+	return base_elt;
-+      }
-+
-+    default:
-+      return 0;
-+    }
-+}
-+#endif
-+
-+
- /* ffi_prep_args64 is called by the assembly routine once stack space
-    has been allocated for the function's arguments.
- 
-    The stack layout we want looks like this:
- 
-    |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses
-    |--------------------------------------------|
-    |   CR save area			8bytes	|
-@@ -418,141 +469,216 @@ ffi_prep_args64 (extended_cif *ecif, uns
-   const unsigned long bytes = ecif->cif->bytes;
-   const unsigned long flags = ecif->cif->flags;
- 
-   typedef union {
-     char *c;
-     unsigned long *ul;
-     float *f;
-     double *d;
-+    size_t p;
-   } valp;
- 
-   /* 'stacktop' points at the previous backchain pointer.  */
-   valp stacktop;
- 
-   /* 'next_arg' points at the space for gpr3, and grows upwards as
-      we use GPR registers, then continues at rest.  */
-   valp gpr_base;
-   valp gpr_end;
-   valp rest;
-   valp next_arg;
- 
-   /* 'fpr_base' points at the space for fpr3, and grows upwards as
-      we use FPR registers.  */
-   valp fpr_base;
--  int fparg_count;
-+  unsigned int fparg_count;
- 
--  int i, words;
-+  unsigned int i, words, nargs, nfixedargs;
-   ffi_type **ptr;
-   double double_tmp;
-   union {
-     void **v;
-     char **c;
-     signed char **sc;
-     unsigned char **uc;
-     signed short **ss;
-     unsigned short **us;
-     signed int **si;
-     unsigned int **ui;
-     unsigned long **ul;
-     float **f;
-     double **d;
-   } p_argv;
-   unsigned long gprvalue;
-+#ifdef __STRUCT_PARM_ALIGN__
-+  unsigned long align;
-+#endif
- 
-   stacktop.c = (char *) stack + bytes;
-   gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
-   gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
-+#if _CALL_ELF == 2
-+  rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64;
-+#else
-   rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
-+#endif
-   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
-   fparg_count = 0;
-   next_arg.ul = gpr_base.ul;
- 
-   /* Check that everything starts aligned properly.  */
-   FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
-   FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
-   FFI_ASSERT ((bytes & 0xF) == 0);
- 
-   /* Deal with return values that are actually pass-by-reference.  */
-   if (flags & FLAG_RETVAL_REFERENCE)
-     *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
- 
-   /* Now for the arguments.  */
-   p_argv.v = ecif->avalue;
--  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
--       i > 0;
--       i--, ptr++, p_argv.v++)
-+  nargs = ecif->cif->nargs;
-+  nfixedargs = ecif->cif->nfixedargs;
-+  for (ptr = ecif->cif->arg_types, i = 0;
-+       i < nargs;
-+       i++, ptr++, p_argv.v++)
-     {
-+      unsigned int elt, elnum;
-+
-       switch ((*ptr)->type)
- 	{
- 	case FFI_TYPE_FLOAT:
- 	  double_tmp = **p_argv.f;
--	  *next_arg.f = (float) double_tmp;
-+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
-+	    *fpr_base.d++ = double_tmp;
-+	  else
-+	    *next_arg.f = (float) double_tmp;
- 	  if (++next_arg.ul == gpr_end.ul)
- 	    next_arg.ul = rest.ul;
--	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
--	    *fpr_base.d++ = double_tmp;
- 	  fparg_count++;
- 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
- 	  break;
- 
- 	case FFI_TYPE_DOUBLE:
- 	  double_tmp = **p_argv.d;
--	  *next_arg.d = double_tmp;
-+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
-+	    *fpr_base.d++ = double_tmp;
-+	  else
-+	    *next_arg.d = double_tmp;
- 	  if (++next_arg.ul == gpr_end.ul)
- 	    next_arg.ul = rest.ul;
--	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
--	    *fpr_base.d++ = double_tmp;
- 	  fparg_count++;
- 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
- 	  break;
- 
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- 	case FFI_TYPE_LONGDOUBLE:
- 	  double_tmp = (*p_argv.d)[0];
--	  *next_arg.d = double_tmp;
-+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
-+	    *fpr_base.d++ = double_tmp;
-+	  else
-+	    *next_arg.d = double_tmp;
- 	  if (++next_arg.ul == gpr_end.ul)
- 	    next_arg.ul = rest.ul;
--	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
--	    *fpr_base.d++ = double_tmp;
- 	  fparg_count++;
- 	  double_tmp = (*p_argv.d)[1];
--	  *next_arg.d = double_tmp;
-+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
-+	    *fpr_base.d++ = double_tmp;
-+	  else
-+	    *next_arg.d = double_tmp;
- 	  if (++next_arg.ul == gpr_end.ul)
- 	    next_arg.ul = rest.ul;
--	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
--	    *fpr_base.d++ = double_tmp;
- 	  fparg_count++;
- 	  FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
- 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
- 	  break;
- #endif
- 
- 	case FFI_TYPE_STRUCT:
--	  words = ((*ptr)->size + 7) / 8;
--	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
-+#ifdef __STRUCT_PARM_ALIGN__
-+	  align = (*ptr)->alignment;
-+	  if (align > __STRUCT_PARM_ALIGN__)
-+	    align = __STRUCT_PARM_ALIGN__;
-+	  if (align > 1)
-+	    next_arg.p = ALIGN (next_arg.p, align);
-+#endif
-+	  elt = 0;
-+#if _CALL_ELF == 2
-+	  elt = discover_homogeneous_aggregate (*ptr, &elnum);
-+#endif
-+	  if (elt)
- 	    {
--	      size_t first = gpr_end.c - next_arg.c;
--	      memcpy (next_arg.c, *p_argv.c, first);
--	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
--	      next_arg.c = rest.c + words * 8 - first;
-+	      union {
-+		void *v;
-+		float *f;
-+		double *d;
-+	      } arg;
-+
-+	      arg.v = *p_argv.v;
-+	      if (elt == FFI_TYPE_FLOAT)
-+		{
-+		  do
-+		    {
-+		      double_tmp = *arg.f++;
-+		      if (fparg_count < NUM_FPR_ARG_REGISTERS64
-+			  && i < nfixedargs)
-+			*fpr_base.d++ = double_tmp;
-+		      else
-+			*next_arg.f = (float) double_tmp;
-+		      if (++next_arg.f == gpr_end.f)
-+			next_arg.f = rest.f;
-+		      fparg_count++;
-+		    }
-+		  while (--elnum != 0);
-+		  if ((next_arg.p & 3) != 0)
-+		    {
-+		      if (++next_arg.f == gpr_end.f)
-+			next_arg.f = rest.f;
-+		    }
-+		}
-+	      else
-+		do
-+		  {
-+		    double_tmp = *arg.d++;
-+		    if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
-+		      *fpr_base.d++ = double_tmp;
-+		    else
-+		      *next_arg.d = double_tmp;
-+		    if (++next_arg.d == gpr_end.d)
-+		      next_arg.d = rest.d;
-+		    fparg_count++;
-+		  }
-+		while (--elnum != 0);
- 	    }
- 	  else
- 	    {
--	      char *where = next_arg.c;
-+	      words = ((*ptr)->size + 7) / 8;
-+	      if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
-+		{
-+		  size_t first = gpr_end.c - next_arg.c;
-+		  memcpy (next_arg.c, *p_argv.c, first);
-+		  memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
-+		  next_arg.c = rest.c + words * 8 - first;
-+		}
-+	      else
-+		{
-+		  char *where = next_arg.c;
- 
--	      /* Structures with size less than eight bytes are passed
--		 left-padded.  */
--	      if ((*ptr)->size < 8)
--		where += 8 - (*ptr)->size;
--
--	      memcpy (where, *p_argv.c, (*ptr)->size);
--	      next_arg.ul += words;
--	      if (next_arg.ul == gpr_end.ul)
--		next_arg.ul = rest.ul;
-+#ifndef __LITTLE_ENDIAN__
-+		  /* Structures with size less than eight bytes are passed
-+		     left-padded.  */
-+		  if ((*ptr)->size < 8)
-+		    where += 8 - (*ptr)->size;
-+#endif
-+		  memcpy (where, *p_argv.c, (*ptr)->size);
-+		  next_arg.ul += words;
-+		  if (next_arg.ul == gpr_end.ul)
-+		    next_arg.ul = rest.ul;
-+		}
- 	    }
- 	  break;
- 
- 	case FFI_TYPE_UINT8:
- 	  gprvalue = **p_argv.uc;
- 	  goto putgpr;
- 	case FFI_TYPE_SINT8:
- 	  gprvalue = **p_argv.sc;
-@@ -586,53 +712,55 @@ ffi_prep_args64 (extended_cif *ecif, uns
-   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
- 	      || (next_arg.ul >= gpr_base.ul
- 		  && next_arg.ul <= gpr_base.ul + 4));
- }
- 
- 
- 
- /* Perform machine dependent cif processing */
--ffi_status
--ffi_prep_cif_machdep (ffi_cif *cif)
-+static ffi_status
-+ffi_prep_cif_machdep_core (ffi_cif *cif)
- {
-   /* All this is for the SYSV and LINUX64 ABI.  */
--  int i;
-   ffi_type **ptr;
-   unsigned bytes;
--  int fparg_count = 0, intarg_count = 0;
--  unsigned flags = 0;
-+  unsigned i, fparg_count = 0, intarg_count = 0;
-+  unsigned flags = cif->flags;
-   unsigned struct_copy_size = 0;
-   unsigned type = cif->rtype->type;
-   unsigned size = cif->rtype->size;
- 
--  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--    NUM_FPR_ARG_REGISTERS = 0;
--
-+  /* The machine-independent calculation of cif->bytes doesn't work
-+     for us.  Redo the calculation.  */
-   if (cif->abi != FFI_LINUX64)
-     {
--      /* All the machine-independent calculation of cif->bytes will be wrong.
--	 Redo the calculation for SYSV.  */
--
-       /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
-       bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
- 
-       /* Space for the GPR registers.  */
-       bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
-     }
-   else
-     {
-       /* 64-bit ABI.  */
-+#if _CALL_ELF == 2
-+      /* Space for backchain, CR, LR, TOC and the asm's temp regs.  */
-+      bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long);
- 
-+      /* Space for the general registers.  */
-+      bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long);
-+#else
-       /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
- 	 regs.  */
-       bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
- 
-       /* Space for the mandatory parm save area and general registers.  */
-       bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
-+#endif
-     }
- 
-   /* Return value handling.  The rules for SYSV are as follows:
-      - 32-bit (or less) integer values are returned in gpr3;
-      - Structures of size <= 4 bytes also returned in gpr3;
-      - 64-bit integer values and structures between 5 and 8 bytes are returned
-      in gpr3 and gpr4;
-      - Single/double FP values are returned in fpr1;
-@@ -641,71 +769,93 @@ ffi_prep_cif_machdep (ffi_cif *cif)
-      - long doubles (if not equivalent to double) are returned in
-      fpr1,fpr2 for Linux and as for large structs for SysV.
-      For LINUX64:
-      - integer values in gpr3;
-      - Structures/Unions by reference;
-      - Single/double FP values in fpr1, long double in fpr1,fpr2.
-      - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
-      - soft-float long doubles are returned in gpr3-gpr6.  */
-+  /* First translate for softfloat/nonlinux */
-+  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
-+    {
-+      if (type == FFI_TYPE_FLOAT)
-+	type = FFI_TYPE_UINT32;
-+      if (type == FFI_TYPE_DOUBLE)
-+	type = FFI_TYPE_UINT64;
-+      if (type == FFI_TYPE_LONGDOUBLE)
-+	type = FFI_TYPE_UINT128;
-+    }
-+  else if (cif->abi != FFI_LINUX
-+	   && cif->abi != FFI_LINUX64)
-+    {
-+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-+      if (type == FFI_TYPE_LONGDOUBLE)
-+	type = FFI_TYPE_STRUCT;
-+#endif
-+    }
-+
-   switch (type)
-     {
-+#ifndef __NO_FPRS__
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-     case FFI_TYPE_LONGDOUBLE:
--      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
--	&& cif->abi != FFI_LINUX_SOFT_FLOAT)
--	goto byref;
-       flags |= FLAG_RETURNS_128BITS;
-       /* Fall through.  */
- #endif
-     case FFI_TYPE_DOUBLE:
-       flags |= FLAG_RETURNS_64BITS;
-       /* Fall through.  */
-     case FFI_TYPE_FLOAT:
--      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
--      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
--	flags |= FLAG_RETURNS_FP;
-+      flags |= FLAG_RETURNS_FP;
-       break;
-+#endif
- 
-+    case FFI_TYPE_UINT128:
-+      flags |= FLAG_RETURNS_128BITS;
-+      /* Fall through.  */
-     case FFI_TYPE_UINT64:
-     case FFI_TYPE_SINT64:
-       flags |= FLAG_RETURNS_64BITS;
-       break;
- 
-     case FFI_TYPE_STRUCT:
--      if (cif->abi == FFI_SYSV)
-+      /*
-+       * The final SYSV ABI says that structures smaller or equal 8 bytes
-+       * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
-+       * in memory.
-+       *
-+       * NOTE: The assembly code can safely assume that it just needs to
-+       *       store both r3 and r4 into a 8-byte word-aligned buffer, as
-+       *       we allocate a temporary buffer in ffi_call() if this flag is
-+       *       set.
-+       */
-+      if (cif->abi == FFI_SYSV && size <= 8)
- 	{
--	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
--	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
--	     in memory.  */
--
--	  /* Treat structs with size <= 8 bytes.  */
--	  if (size <= 8)
-+	  flags |= FLAG_RETURNS_SMST;
-+	  break;
-+	}
-+#if _CALL_ELF == 2
-+      if (cif->abi == FFI_LINUX64)
-+	{
-+	  unsigned int elt, elnum;
-+	  elt = discover_homogeneous_aggregate (cif->rtype, &elnum);
-+	  if (elt)
-+	    {
-+	      if (elt == FFI_TYPE_DOUBLE)
-+		flags |= FLAG_RETURNS_64BITS;
-+	      flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST;
-+	      break;
-+	    }
-+	  if (size <= 16)
- 	    {
- 	      flags |= FLAG_RETURNS_SMST;
--	      /* These structs are returned in r3. We pack the type and the
--		 precalculated shift value (needed in the sysv.S) into flags.
--		 The same applies for the structs returned in r3/r4.  */
--	      if (size <= 4)
--		{
--		  flags |= FLAG_SYSV_SMST_R3;
--		  flags |= 8 * (4 - size) << 8;
--		  break;
--		}
--	      /* These structs are returned in r3 and r4. See above.   */
--	      if  (size <= 8)
--		{
--		  flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
--		  flags |= 8 * (8 - size) << 8;
--		  break;
--		}
-+	      break;
- 	    }
- 	}
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--    byref:
- #endif
-       intarg_count++;
-       flags |= FLAG_RETVAL_REFERENCE;
-       /* Fall through.  */
-     case FFI_TYPE_VOID:
-       flags |= FLAG_RETURNS_NOTHING;
-       break;
- 
-@@ -717,218 +867,334 @@ ffi_prep_cif_machdep (ffi_cif *cif)
-   if (cif->abi != FFI_LINUX64)
-     /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
-        first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
-        goes on the stack.  Structures and long doubles (if not equivalent
-        to double) are passed as a pointer to a copy of the structure.
-        Stuff on the stack needs to keep proper alignment.  */
-     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
-       {
--	switch ((*ptr)->type)
--	  {
-+	unsigned short typenum = (*ptr)->type;
-+
-+	/* We may need to handle some values depending on ABI */
-+	if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
-+		if (typenum == FFI_TYPE_FLOAT)
-+			typenum = FFI_TYPE_UINT32;
-+		if (typenum == FFI_TYPE_DOUBLE)
-+			typenum = FFI_TYPE_UINT64;
-+		if (typenum == FFI_TYPE_LONGDOUBLE)
-+			typenum = FFI_TYPE_UINT128;
-+	} else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
-+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-+		if (typenum == FFI_TYPE_LONGDOUBLE)
-+			typenum = FFI_TYPE_STRUCT;
-+#endif
-+	}
-+
-+	switch (typenum) {
-+#ifndef __NO_FPRS__
- 	  case FFI_TYPE_FLOAT:
--	    /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
--	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--	      goto soft_float_cif;
- 	    fparg_count++;
- 	    /* floating singles are not 8-aligned on stack */
- 	    break;
- 
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- 	  case FFI_TYPE_LONGDOUBLE:
--	    if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
--	      goto do_struct;
--	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--	      {
--		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
--		  || intarg_count < NUM_GPR_ARG_REGISTERS)
--		  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
--		     a set of four consecutive gprs. If we have not enough,
--		     we have to adjust the intarg_count value.  */
--		  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
--		intarg_count += 4;
--		break;
--	      }
--	    else
--	      fparg_count++;
-+	    fparg_count++;
- 	    /* Fall thru */
- #endif
- 	  case FFI_TYPE_DOUBLE:
--	    /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
--	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--	      goto soft_double_cif;
- 	    fparg_count++;
- 	    /* If this FP arg is going on the stack, it must be
- 	       8-byte-aligned.  */
- 	    if (fparg_count > NUM_FPR_ARG_REGISTERS
- 		&& intarg_count >= NUM_GPR_ARG_REGISTERS
- 		&& intarg_count % 2 != 0)
- 	      intarg_count++;
- 	    break;
-+#endif
-+	  case FFI_TYPE_UINT128:
-+		/*
-+		 * A long double in FFI_LINUX_SOFT_FLOAT can use only a set
-+		 * of four consecutive gprs. If we do not have enough, we
-+		 * have to adjust the intarg_count value.
-+		 */
-+		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
-+				&& intarg_count < NUM_GPR_ARG_REGISTERS)
-+			intarg_count = NUM_GPR_ARG_REGISTERS;
-+		intarg_count += 4;
-+		break;
- 
- 	  case FFI_TYPE_UINT64:
- 	  case FFI_TYPE_SINT64:
--	  soft_double_cif:
- 	    /* 'long long' arguments are passed as two words, but
- 	       either both words must fit in registers or both go
- 	       on the stack.  If they go on the stack, they must
- 	       be 8-byte-aligned.
- 
- 	       Also, only certain register pairs can be used for
- 	       passing long long int -- specifically (r3,r4), (r5,r6),
- 	       (r7,r8), (r9,r10).
- 	    */
- 	    if (intarg_count == NUM_GPR_ARG_REGISTERS-1
- 		|| intarg_count % 2 != 0)
- 	      intarg_count++;
- 	    intarg_count += 2;
- 	    break;
- 
- 	  case FFI_TYPE_STRUCT:
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--	  do_struct:
--#endif
- 	    /* We must allocate space for a copy of these to enforce
- 	       pass-by-value.  Pad the space up to a multiple of 16
- 	       bytes (the maximum alignment required for anything under
- 	       the SYSV ABI).  */
- 	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
- 	    /* Fall through (allocate space for the pointer).  */
- 
--	  default:
--	  soft_float_cif:
-+	  case FFI_TYPE_POINTER:
-+	  case FFI_TYPE_INT:
-+	  case FFI_TYPE_UINT32:
-+	  case FFI_TYPE_SINT32:
-+	  case FFI_TYPE_UINT16:
-+	  case FFI_TYPE_SINT16:
-+	  case FFI_TYPE_UINT8:
-+	  case FFI_TYPE_SINT8:
- 	    /* Everything else is passed as a 4-byte word in a GPR, either
- 	       the object itself or a pointer to it.  */
- 	    intarg_count++;
- 	    break;
-+	  default:
-+		FFI_ASSERT (0);
- 	  }
-       }
-   else
-     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
-       {
-+	unsigned int elt, elnum;
-+#ifdef __STRUCT_PARM_ALIGN__
-+	unsigned int align;
-+#endif
-+
- 	switch ((*ptr)->type)
- 	  {
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- 	  case FFI_TYPE_LONGDOUBLE:
--	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--	      intarg_count += 4;
--	    else
--	      {
--		fparg_count += 2;
--		intarg_count += 2;
--	      }
-+	    fparg_count += 2;
-+	    intarg_count += 2;
-+	    if (fparg_count > NUM_FPR_ARG_REGISTERS)
-+	      flags |= FLAG_ARG_NEEDS_PSAVE;
- 	    break;
- #endif
- 	  case FFI_TYPE_FLOAT:
- 	  case FFI_TYPE_DOUBLE:
- 	    fparg_count++;
- 	    intarg_count++;
-+	    if (fparg_count > NUM_FPR_ARG_REGISTERS)
-+	      flags |= FLAG_ARG_NEEDS_PSAVE;
- 	    break;
- 
- 	  case FFI_TYPE_STRUCT:
-+#ifdef __STRUCT_PARM_ALIGN__
-+	    align = (*ptr)->alignment;
-+	    if (align > __STRUCT_PARM_ALIGN__)
-+	      align = __STRUCT_PARM_ALIGN__;
-+	    align = align / 8;
-+	    if (align > 1)
-+	      intarg_count = ALIGN (intarg_count, align);
-+#endif
- 	    intarg_count += ((*ptr)->size + 7) / 8;
-+	    elt = 0;
-+#if _CALL_ELF == 2
-+	    elt = discover_homogeneous_aggregate (*ptr, &elnum);
-+#endif
-+	    if (elt)
-+	      {
-+		fparg_count += elnum;
-+		if (fparg_count > NUM_FPR_ARG_REGISTERS)
-+		  flags |= FLAG_ARG_NEEDS_PSAVE;
-+	      }
-+	    else
-+	      {
-+		if (intarg_count > NUM_GPR_ARG_REGISTERS)
-+		  flags |= FLAG_ARG_NEEDS_PSAVE;
-+	      }
- 	    break;
- 
--	  default:
-+	  case FFI_TYPE_POINTER:
-+	  case FFI_TYPE_UINT64:
-+	  case FFI_TYPE_SINT64:
-+	  case FFI_TYPE_INT:
-+	  case FFI_TYPE_UINT32:
-+	  case FFI_TYPE_SINT32:
-+	  case FFI_TYPE_UINT16:
-+	  case FFI_TYPE_SINT16:
-+	  case FFI_TYPE_UINT8:
-+	  case FFI_TYPE_SINT8:
- 	    /* Everything else is passed as a 8-byte word in a GPR, either
- 	       the object itself or a pointer to it.  */
- 	    intarg_count++;
-+	    if (intarg_count > NUM_GPR_ARG_REGISTERS)
-+	      flags |= FLAG_ARG_NEEDS_PSAVE;
- 	    break;
-+	  default:
-+	    FFI_ASSERT (0);
- 	  }
-       }
- 
-+#ifndef __NO_FPRS__
-   if (fparg_count != 0)
-     flags |= FLAG_FP_ARGUMENTS;
-+#endif
-   if (intarg_count > 4)
-     flags |= FLAG_4_GPR_ARGUMENTS;
-   if (struct_copy_size != 0)
-     flags |= FLAG_ARG_NEEDS_COPY;
- 
-   if (cif->abi != FFI_LINUX64)
-     {
-+#ifndef __NO_FPRS__
-       /* Space for the FPR registers, if needed.  */
-       if (fparg_count != 0)
- 	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
-+#endif
- 
-       /* Stack space.  */
-       if (intarg_count > NUM_GPR_ARG_REGISTERS)
- 	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
-+#ifndef __NO_FPRS__
-       if (fparg_count > NUM_FPR_ARG_REGISTERS)
- 	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
-+#endif
-     }
-   else
-     {
-+#ifndef __NO_FPRS__
-       /* Space for the FPR registers, if needed.  */
-       if (fparg_count != 0)
- 	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
-+#endif
- 
-       /* Stack space.  */
-+#if _CALL_ELF == 2
-+      if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0)
-+	bytes += intarg_count * sizeof (long);
-+#else
-       if (intarg_count > NUM_GPR_ARG_REGISTERS64)
- 	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
-+#endif
-     }
- 
-   /* The stack space allocated needs to be a multiple of 16 bytes.  */
-   bytes = (bytes + 15) & ~0xF;
- 
-   /* Add in the space for the copied structures.  */
-   bytes += struct_copy_size;
- 
-   cif->flags = flags;
-   cif->bytes = bytes;
- 
-   return FFI_OK;
- }
- 
-+ffi_status
-+ffi_prep_cif_machdep (ffi_cif *cif)
-+{
-+  cif->nfixedargs = cif->nargs;
-+  return ffi_prep_cif_machdep_core (cif);
-+}
-+
-+ffi_status
-+ffi_prep_cif_machdep_var (ffi_cif *cif,
-+			  unsigned int nfixedargs,
-+			  unsigned int ntotalargs MAYBE_UNUSED)
-+{
-+  cif->nfixedargs = nfixedargs;
-+#if _CALL_ELF == 2
-+  if (cif->abi == FFI_LINUX64)
-+    cif->flags |= FLAG_ARG_NEEDS_PSAVE;
-+#endif
-+  return ffi_prep_cif_machdep_core (cif);
-+}
-+
- extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
- 			  void (*fn)(void));
- extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
- 					unsigned long, unsigned long *,
- 					void (*fn)(void));
- 
- void
- ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
- {
-+  /*
-+   * The final SYSV ABI says that structures smaller or equal 8 bytes
-+   * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
-+   * in memory.
-+   *
-+   * We bounce-buffer SYSV small struct return values so that sysv.S
-+   * can write r3 and r4 to memory without worrying about struct size.
-+   *
-+   * For ELFv2 ABI, use a bounce buffer for homogeneous structs too,
-+   * for similar reasons.
-+   */
-+  unsigned long smst_buffer[8];
-   extended_cif ecif;
- 
-   ecif.cif = cif;
-   ecif.avalue = avalue;
- 
--  /* If the return value is a struct and we don't have a return	*/
--  /* value address then we need to make one		        */
--
--  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
--    {
--      ecif.rvalue = alloca(cif->rtype->size);
--    }
--  else
--    ecif.rvalue = rvalue;
--
-+  ecif.rvalue = rvalue;
-+  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
-+    ecif.rvalue = smst_buffer;
-+  /* Ensure that we have a valid struct return value.
-+     FIXME: Isn't this just papering over a user problem?  */
-+  else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT)
-+    ecif.rvalue = alloca (cif->rtype->size);
- 
-   switch (cif->abi)
-     {
- #ifndef POWERPC64
-+# ifndef __NO_FPRS__
-     case FFI_SYSV:
-     case FFI_GCC_SYSV:
-     case FFI_LINUX:
-+# endif
-     case FFI_LINUX_SOFT_FLOAT:
-       ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
-       break;
- #else
-     case FFI_LINUX64:
-       ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
-       break;
- #endif
-     default:
-       FFI_ASSERT (0);
-       break;
-     }
-+
-+  /* Check for a bounce-buffered return value */
-+  if (rvalue && ecif.rvalue == smst_buffer)
-+    {
-+      unsigned int rsize = cif->rtype->size;
-+#ifndef __LITTLE_ENDIAN__
-+      /* The SYSV ABI returns a structure of up to 4 bytes in size
-+	 left-padded in r3.  */
-+      if (cif->abi == FFI_SYSV && rsize <= 4)
-+	memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize);
-+      /* The SYSV ABI returns a structure of up to 8 bytes in size
-+	 left-padded in r3/r4, and the ELFv2 ABI similarly returns a
-+	 structure of up to 8 bytes in size left-padded in r3.  */
-+      else if (rsize <= 8)
-+	memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
-+      else
-+#endif
-+	memcpy (rvalue, smst_buffer, rsize);
-+    }
- }
- 
- 
--#ifndef POWERPC64
-+#if !defined POWERPC64 || _CALL_ELF == 2
- #define MIN_CACHE_LINE_SIZE 8
- 
- static void
- flush_icache (char *wraddr, char *xaddr, int size)
- {
-   int i;
-   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
-     __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
-@@ -942,26 +1208,48 @@ flush_icache (char *wraddr, char *xaddr,
- ffi_status
- ffi_prep_closure_loc (ffi_closure *closure,
- 		      ffi_cif *cif,
- 		      void (*fun) (ffi_cif *, void *, void **, void *),
- 		      void *user_data,
- 		      void *codeloc)
- {
- #ifdef POWERPC64
-+# if _CALL_ELF == 2
-+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
-+
-+  if (cif->abi != FFI_LINUX64)
-+    return FFI_BAD_ABI;
-+
-+  tramp[0] = 0xe96c0018;	/* 0:	ld	11,2f-0b(12)	*/
-+  tramp[1] = 0xe98c0010;	/*	ld	12,1f-0b(12)	*/
-+  tramp[2] = 0x7d8903a6;	/*	mtctr	12		*/
-+  tramp[3] = 0x4e800420;	/*	bctr			*/
-+				/* 1:	.quad	function_addr	*/
-+				/* 2:	.quad	context		*/
-+  *(void **) &tramp[4] = (void *) ffi_closure_LINUX64;
-+  *(void **) &tramp[6] = codeloc;
-+  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
-+# else
-   void **tramp = (void **) &closure->tramp[0];
- 
--  FFI_ASSERT (cif->abi == FFI_LINUX64);
-+  if (cif->abi != FFI_LINUX64)
-+    return FFI_BAD_ABI;
-   /* Copy function address and TOC from ffi_closure_LINUX64.  */
-   memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
-   tramp[2] = codeloc;
-+# endif
- #else
-   unsigned int *tramp;
- 
--  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
-+  if (! (cif->abi == FFI_GCC_SYSV 
-+	 || cif->abi == FFI_SYSV
-+	 || cif->abi == FFI_LINUX
-+	 || cif->abi == FFI_LINUX_SOFT_FLOAT))
-+    return FFI_BAD_ABI;
- 
-   tramp = (unsigned int *) &closure->tramp[0];
-   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
-   tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
-   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
-   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
-   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
-   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
-@@ -1006,110 +1294,215 @@ ffi_closure_helper_SYSV (ffi_closure *cl
-   /* rvalue is the pointer to space for return value in closure assembly */
-   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
-   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
-   /* pst is the pointer to outgoing parameter stack in original caller */
- 
-   void **          avalue;
-   ffi_type **      arg_types;
-   long             i, avn;
--  long             nf;   /* number of floating registers already used */
--  long             ng;   /* number of general registers already used */
--  ffi_cif *        cif;
--  double           temp;
--  unsigned         size;
-+#ifndef __NO_FPRS__
-+  long             nf = 0;   /* number of floating registers already used */
-+#endif
-+  long             ng = 0;   /* number of general registers already used */
- 
--  cif = closure->cif;
-+  ffi_cif *cif = closure->cif;
-+  unsigned       size     = cif->rtype->size;
-+  unsigned short rtypenum = cif->rtype->type;
-+
-   avalue = alloca (cif->nargs * sizeof (void *));
--  size = cif->rtype->size;
- 
--  nf = 0;
--  ng = 0;
-+  /* First translate for softfloat/nonlinux */
-+  if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
-+	if (rtypenum == FFI_TYPE_FLOAT)
-+		rtypenum = FFI_TYPE_UINT32;
-+	if (rtypenum == FFI_TYPE_DOUBLE)
-+		rtypenum = FFI_TYPE_UINT64;
-+	if (rtypenum == FFI_TYPE_LONGDOUBLE)
-+		rtypenum = FFI_TYPE_UINT128;
-+  } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
-+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-+	if (rtypenum == FFI_TYPE_LONGDOUBLE)
-+		rtypenum = FFI_TYPE_STRUCT;
-+#endif
-+  }
-+
- 
-   /* Copy the caller's structure return value address so that the closure
-      returns the data directly to the caller.
-      For FFI_SYSV the result is passed in r3/r4 if the struct size is less
-      or equal 8 bytes.  */
--
--  if ((cif->rtype->type == FFI_TYPE_STRUCT
--       && !((cif->abi == FFI_SYSV) && (size <= 8)))
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
--	  && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
--#endif
--      )
--    {
-+  if (rtypenum == FFI_TYPE_STRUCT && ((cif->abi != FFI_SYSV) || (size > 8))) {
-       rvalue = (void *) *pgr;
-       ng++;
-       pgr++;
-     }
- 
-   i = 0;
-   avn = cif->nargs;
-   arg_types = cif->arg_types;
- 
-   /* Grab the addresses of the arguments from the stack frame.  */
--  while (i < avn)
--    {
--      switch (arg_types[i]->type)
--	{
-+  while (i < avn) {
-+      unsigned short typenum = arg_types[i]->type;
-+
-+      /* We may need to handle some values depending on ABI */
-+      if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
-+		if (typenum == FFI_TYPE_FLOAT)
-+			typenum = FFI_TYPE_UINT32;
-+		if (typenum == FFI_TYPE_DOUBLE)
-+			typenum = FFI_TYPE_UINT64;
-+		if (typenum == FFI_TYPE_LONGDOUBLE)
-+			typenum = FFI_TYPE_UINT128;
-+      } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
-+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-+		if (typenum == FFI_TYPE_LONGDOUBLE)
-+			typenum = FFI_TYPE_STRUCT;
-+#endif
-+      }
-+
-+      switch (typenum) {
-+#ifndef __NO_FPRS__
-+	case FFI_TYPE_FLOAT:
-+	  /* unfortunately float values are stored as doubles
-+	   * in the ffi_closure_SYSV code (since we don't check
-+	   * the type in that routine).
-+	   */
-+
-+	  /* there are 8 64bit floating point registers */
-+
-+	  if (nf < 8)
-+	    {
-+	      double temp = pfr->d;
-+	      pfr->f = (float) temp;
-+	      avalue[i] = pfr;
-+	      nf++;
-+	      pfr++;
-+	    }
-+	  else
-+	    {
-+	      /* FIXME? here we are really changing the values
-+	       * stored in the original calling routines outgoing
-+	       * parameter stack.  This is probably a really
-+	       * naughty thing to do but...
-+	       */
-+	      avalue[i] = pst;
-+	      pst += 1;
-+	    }
-+	  break;
-+
-+	case FFI_TYPE_DOUBLE:
-+	  /* On the outgoing stack all values are aligned to 8 */
-+	  /* there are 8 64bit floating point registers */
-+
-+	  if (nf < 8)
-+	    {
-+	      avalue[i] = pfr;
-+	      nf++;
-+	      pfr++;
-+	    }
-+	  else
-+	    {
-+	      if (((long) pst) & 4)
-+		pst++;
-+	      avalue[i] = pst;
-+	      pst += 2;
-+	    }
-+	  break;
-+
-+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-+	case FFI_TYPE_LONGDOUBLE:
-+	  if (nf < 7)
-+	    {
-+	      avalue[i] = pfr;
-+	      pfr += 2;
-+	      nf += 2;
-+	    }
-+	  else
-+	    {
-+	      if (((long) pst) & 4)
-+		pst++;
-+	      avalue[i] = pst;
-+	      pst += 4;
-+	      nf = 8;
-+	    }
-+	  break;
-+#endif
-+#endif /* have FPRS */
-+
-+	case FFI_TYPE_UINT128:
-+		/*
-+		 * Test if for the whole long double, 4 gprs are available.
-+		 * otherwise the stuff ends up on the stack.
-+		 */
-+		if (ng < 5) {
-+			avalue[i] = pgr;
-+			pgr += 4;
-+			ng += 4;
-+		} else {
-+			avalue[i] = pst;
-+			pst += 4;
-+			ng = 8+4;
-+		}
-+		break;
-+
- 	case FFI_TYPE_SINT8:
- 	case FFI_TYPE_UINT8:
-+#ifndef __LITTLE_ENDIAN__
- 	  /* there are 8 gpr registers used to pass values */
- 	  if (ng < 8)
- 	    {
- 	      avalue[i] = (char *) pgr + 3;
- 	      ng++;
- 	      pgr++;
- 	    }
- 	  else
- 	    {
- 	      avalue[i] = (char *) pst + 3;
- 	      pst++;
- 	    }
- 	  break;
-+#endif
- 
- 	case FFI_TYPE_SINT16:
- 	case FFI_TYPE_UINT16:
-+#ifndef __LITTLE_ENDIAN__
- 	  /* there are 8 gpr registers used to pass values */
- 	  if (ng < 8)
- 	    {
- 	      avalue[i] = (char *) pgr + 2;
- 	      ng++;
- 	      pgr++;
- 	    }
- 	  else
- 	    {
- 	      avalue[i] = (char *) pst + 2;
- 	      pst++;
- 	    }
- 	  break;
-+#endif
- 
- 	case FFI_TYPE_SINT32:
- 	case FFI_TYPE_UINT32:
- 	case FFI_TYPE_POINTER:
--	soft_float_closure:
- 	  /* there are 8 gpr registers used to pass values */
- 	  if (ng < 8)
- 	    {
- 	      avalue[i] = pgr;
- 	      ng++;
- 	      pgr++;
- 	    }
- 	  else
- 	    {
- 	      avalue[i] = pst;
- 	      pst++;
- 	    }
- 	  break;
- 
- 	case FFI_TYPE_STRUCT:
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--	do_struct:
--#endif
- 	  /* Structs are passed by reference. The address will appear in a
- 	     gpr if it is one of the first 8 arguments.  */
- 	  if (ng < 8)
- 	    {
- 	      avalue[i] = (void *) *pgr;
- 	      ng++;
- 	      pgr++;
- 	    }
-@@ -1117,17 +1510,16 @@ ffi_closure_helper_SYSV (ffi_closure *cl
- 	    {
- 	      avalue[i] = (void *) *pst;
- 	      pst++;
- 	    }
- 	  break;
- 
- 	case FFI_TYPE_SINT64:
- 	case FFI_TYPE_UINT64:
--	soft_double_closure:
- 	  /* passing long long ints are complex, they must
- 	   * be passed in suitable register pairs such as
- 	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
- 	   * and if the entire pair aren't available then the outgoing
- 	   * parameter stack is used for both but an alignment of 8
- 	   * must will be kept.  So we must either look in pgr
- 	   * or pst to find the correct address for this type
- 	   * of parameter.
-@@ -1149,277 +1541,239 @@ ffi_closure_helper_SYSV (ffi_closure *cl
- 	      if (((long) pst) & 4)
- 		pst++;
- 	      avalue[i] = pst;
- 	      pst += 2;
- 	      ng = 8;
- 	    }
- 	  break;
- 
--	case FFI_TYPE_FLOAT:
--	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
--	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--	    goto soft_float_closure;
--	  /* unfortunately float values are stored as doubles
--	   * in the ffi_closure_SYSV code (since we don't check
--	   * the type in that routine).
--	   */
--
--	  /* there are 8 64bit floating point registers */
--
--	  if (nf < 8)
--	    {
--	      temp = pfr->d;
--	      pfr->f = (float) temp;
--	      avalue[i] = pfr;
--	      nf++;
--	      pfr++;
--	    }
--	  else
--	    {
--	      /* FIXME? here we are really changing the values
--	       * stored in the original calling routines outgoing
--	       * parameter stack.  This is probably a really
--	       * naughty thing to do but...
--	       */
--	      avalue[i] = pst;
--	      pst += 1;
--	    }
--	  break;
--
--	case FFI_TYPE_DOUBLE:
--	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
--	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--	    goto soft_double_closure;
--	  /* On the outgoing stack all values are aligned to 8 */
--	  /* there are 8 64bit floating point registers */
--
--	  if (nf < 8)
--	    {
--	      avalue[i] = pfr;
--	      nf++;
--	      pfr++;
--	    }
--	  else
--	    {
--	      if (((long) pst) & 4)
--		pst++;
--	      avalue[i] = pst;
--	      pst += 2;
--	    }
--	  break;
--
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--	case FFI_TYPE_LONGDOUBLE:
--	  if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
--	    goto do_struct;
--	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--	    { /* Test if for the whole long double, 4 gprs are available.
--		 otherwise the stuff ends up on the stack.  */
--	      if (ng < 5)
--		{
--		  avalue[i] = pgr;
--		  pgr += 4;
--		  ng += 4;
--		}
--	      else
--		{
--		  avalue[i] = pst;
--		  pst += 4;
--		  ng = 8;
--		}
--	      break;
--	    }
--	  if (nf < 7)
--	    {
--	      avalue[i] = pfr;
--	      pfr += 2;
--	      nf += 2;
--	    }
--	  else
--	    {
--	      if (((long) pst) & 4)
--		pst++;
--	      avalue[i] = pst;
--	      pst += 4;
--	      nf = 8;
--	    }
--	  break;
--#endif
--
- 	default:
--	  FFI_ASSERT (0);
-+		FFI_ASSERT (0);
- 	}
- 
-       i++;
-     }
- 
- 
-   (closure->fun) (cif, rvalue, avalue, closure->user_data);
- 
-   /* Tell ffi_closure_SYSV how to perform return type promotions.
-      Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
-      we have to tell ffi_closure_SYSV how to treat them. We combine the base
-      type FFI_SYSV_TYPE_SMALL_STRUCT - 1  with the size of the struct.
-      So a one byte struct gets the return type 16. Return type 1 to 15 are
-      already used and we never have a struct with size zero. That is the reason
-      for the subtraction of 1. See the comment in ffitarget.h about ordering.
-   */
--  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
--      && size <= 8)
-+  if (cif->abi == FFI_SYSV && rtypenum == FFI_TYPE_STRUCT && size <= 8)
-     return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size;
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
--	   && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
--    return FFI_TYPE_STRUCT;
--#endif
--  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
--     respectivley UINT64.  */
--  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
--    {
--      switch (cif->rtype->type)
--	{
--	case FFI_TYPE_FLOAT:
--	  return FFI_TYPE_UINT32;
--	  break;
--	case FFI_TYPE_DOUBLE:
--	  return FFI_TYPE_UINT64;
--	  break;
--#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--	case FFI_TYPE_LONGDOUBLE:
--	  return FFI_TYPE_UINT128;
--	  break;
--#endif
--	default:
--	  return cif->rtype->type;
--	}
--    }
--  else
--    {
--      return cif->rtype->type;
--    }
-+  return rtypenum;
- }
- 
- int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
- 					   unsigned long *, ffi_dblfl *);
- 
- int FFI_HIDDEN
- ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
- 			    unsigned long *pst, ffi_dblfl *pfr)
- {
-   /* rvalue is the pointer to space for return value in closure assembly */
-   /* pst is the pointer to parameter save area
-      (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
-   /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
- 
-   void **avalue;
-   ffi_type **arg_types;
--  long i, avn;
-+  unsigned long i, avn, nfixedargs;
-   ffi_cif *cif;
-   ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
-+#ifdef __STRUCT_PARM_ALIGN__
-+  unsigned long align;
-+#endif
- 
-   cif = closure->cif;
-   avalue = alloca (cif->nargs * sizeof (void *));
- 
--  /* Copy the caller's structure return value address so that the closure
--     returns the data directly to the caller.  */
--  if (cif->rtype->type == FFI_TYPE_STRUCT)
-+  /* Copy the caller's structure return value address so that the
-+     closure returns the data directly to the caller.  */
-+  if (cif->rtype->type == FFI_TYPE_STRUCT
-+      && (cif->flags & FLAG_RETURNS_SMST) == 0)
-     {
-       rvalue = (void *) *pst;
-       pst++;
-     }
- 
-   i = 0;
-   avn = cif->nargs;
-+  nfixedargs = cif->nfixedargs;
-   arg_types = cif->arg_types;
- 
-   /* Grab the addresses of the arguments from the stack frame.  */
-   while (i < avn)
-     {
-+      unsigned int elt, elnum;
-+
-       switch (arg_types[i]->type)
- 	{
- 	case FFI_TYPE_SINT8:
- 	case FFI_TYPE_UINT8:
-+#ifndef __LITTLE_ENDIAN__
- 	  avalue[i] = (char *) pst + 7;
- 	  pst++;
- 	  break;
-+#endif
- 
- 	case FFI_TYPE_SINT16:
- 	case FFI_TYPE_UINT16:
-+#ifndef __LITTLE_ENDIAN__
- 	  avalue[i] = (char *) pst + 6;
- 	  pst++;
- 	  break;
-+#endif
- 
- 	case FFI_TYPE_SINT32:
- 	case FFI_TYPE_UINT32:
-+#ifndef __LITTLE_ENDIAN__
- 	  avalue[i] = (char *) pst + 4;
- 	  pst++;
- 	  break;
-+#endif
- 
- 	case FFI_TYPE_SINT64:
- 	case FFI_TYPE_UINT64:
- 	case FFI_TYPE_POINTER:
- 	  avalue[i] = pst;
- 	  pst++;
- 	  break;
- 
- 	case FFI_TYPE_STRUCT:
--	  /* Structures with size less than eight bytes are passed
--	     left-padded.  */
--	  if (arg_types[i]->size < 8)
--	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
-+#ifdef __STRUCT_PARM_ALIGN__
-+	  align = arg_types[i]->alignment;
-+	  if (align > __STRUCT_PARM_ALIGN__)
-+	    align = __STRUCT_PARM_ALIGN__;
-+	  if (align > 1)
-+	    pst = (unsigned long *) ALIGN ((size_t) pst, align);
-+#endif
-+	  elt = 0;
-+#if _CALL_ELF == 2
-+	  elt = discover_homogeneous_aggregate (arg_types[i], &elnum);
-+#endif
-+	  if (elt)
-+	    {
-+	      union {
-+		void *v;
-+		unsigned long *ul;
-+		float *f;
-+		double *d;
-+		size_t p;
-+	      } to, from;
-+
-+	      /* Repackage the aggregate from its parts.  The
-+		 aggregate size is not greater than the space taken by
-+		 the registers so store back to the register/parameter
-+		 save arrays.  */
-+	      if (pfr + elnum <= end_pfr)
-+		to.v = pfr;
-+	      else
-+		to.v = pst;
-+
-+	      avalue[i] = to.v;
-+	      from.ul = pst;
-+	      if (elt == FFI_TYPE_FLOAT)
-+		{
-+		  do
-+		    {
-+		      if (pfr < end_pfr && i < nfixedargs)
-+			{
-+			  *to.f = (float) pfr->d;
-+			  pfr++;
-+			}
-+		      else
-+			*to.f = *from.f;
-+		      to.f++;
-+		      from.f++;
-+		    }
-+		  while (--elnum != 0);
-+		}
-+	      else
-+		{
-+		  do
-+		    {
-+		      if (pfr < end_pfr && i < nfixedargs)
-+			{
-+			  *to.d = pfr->d;
-+			  pfr++;
-+			}
-+		      else
-+			*to.d = *from.d;
-+		      to.d++;
-+		      from.d++;
-+		    }
-+		  while (--elnum != 0);
-+		}
-+	    }
- 	  else
--	    avalue[i] = pst;
-+	    {
-+#ifndef __LITTLE_ENDIAN__
-+	      /* Structures with size less than eight bytes are passed
-+		 left-padded.  */
-+	      if (arg_types[i]->size < 8)
-+		avalue[i] = (char *) pst + 8 - arg_types[i]->size;
-+	      else
-+#endif
-+		avalue[i] = pst;
-+	    }
- 	  pst += (arg_types[i]->size + 7) / 8;
- 	  break;
- 
- 	case FFI_TYPE_FLOAT:
- 	  /* unfortunately float values are stored as doubles
- 	   * in the ffi_closure_LINUX64 code (since we don't check
- 	   * the type in that routine).
- 	   */
- 
- 	  /* there are 13 64bit floating point registers */
- 
--	  if (pfr < end_pfr)
-+	  if (pfr < end_pfr && i < nfixedargs)
- 	    {
- 	      double temp = pfr->d;
- 	      pfr->f = (float) temp;
- 	      avalue[i] = pfr;
- 	      pfr++;
- 	    }
- 	  else
- 	    avalue[i] = pst;
- 	  pst++;
- 	  break;
- 
- 	case FFI_TYPE_DOUBLE:
- 	  /* On the outgoing stack all values are aligned to 8 */
- 	  /* there are 13 64bit floating point registers */
- 
--	  if (pfr < end_pfr)
-+	  if (pfr < end_pfr && i < nfixedargs)
- 	    {
- 	      avalue[i] = pfr;
- 	      pfr++;
- 	    }
- 	  else
- 	    avalue[i] = pst;
- 	  pst++;
- 	  break;
- 
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- 	case FFI_TYPE_LONGDOUBLE:
--	  if (pfr + 1 < end_pfr)
-+	  if (pfr + 1 < end_pfr && i + 1 < nfixedargs)
- 	    {
- 	      avalue[i] = pfr;
- 	      pfr += 2;
- 	    }
- 	  else
- 	    {
--	      if (pfr < end_pfr)
-+	      if (pfr < end_pfr && i < nfixedargs)
- 		{
- 		  /* Passed partly in f13 and partly on the stack.
- 		     Move it all to the stack.  */
- 		  *pst = *(unsigned long *) pfr;
- 		  pfr++;
- 		}
- 	      avalue[i] = pst;
- 	    }
-@@ -1433,10 +1787,19 @@ ffi_closure_helper_LINUX64 (ffi_closure 
- 
-       i++;
-     }
- 
- 
-   (closure->fun) (cif, rvalue, avalue, closure->user_data);
- 
-   /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
-+  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
-+    {
-+      if ((cif->flags & FLAG_RETURNS_FP) == 0)
-+	return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1;
-+      else if ((cif->flags & FLAG_RETURNS_64BITS) != 0)
-+	return FFI_V2_TYPE_DOUBLE_HOMOG;
-+      else
-+	return FFI_V2_TYPE_FLOAT_HOMOG;
-+    }
-   return cif->rtype->type;
- }
-diff --git a/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c b/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
---- a/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
-+++ b/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
-@@ -1,14 +1,14 @@
- /* -----------------------------------------------------------------------
-    ffi_darwin.c
- 
-    Copyright (C) 1998 Geoffrey Keating
-    Copyright (C) 2001 John Hornkvist
--   Copyright (C) 2002, 2006, 2007, 2009 Free Software Foundation, Inc.
-+   Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
- 
-    FFI support for Darwin and AIX.
-    
-    Permission is hereby granted, free of charge, to any person obtaining
-    a copy of this software and associated documentation files (the
-    ``Software''), to deal in the Software without restriction, including
-    without limitation the rights to use, copy, modify, merge, publish,
-    distribute, sublicense, and/or sell copies of the Software, and to
-@@ -30,87 +30,112 @@
- #include <ffi.h>
- #include <ffi_common.h>
- 
- #include <stdlib.h>
- 
- extern void ffi_closure_ASM (void);
- 
- enum {
--  /* The assembly depends on these exact flags.  */
--  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7  */
--  FLAG_RETURNS_FP       = 1 << (31-29),
--  FLAG_RETURNS_64BITS   = 1 << (31-28),
--  FLAG_RETURNS_128BITS  = 1 << (31-31),
-+  /* The assembly depends on these exact flags.  
-+     For Darwin64 (when FLAG_RETURNS_STRUCT is set):
-+       FLAG_RETURNS_FP indicates that the structure embeds FP data.
-+       FLAG_RETURNS_128BITS signals a special struct size that is not
-+       expanded for float content.  */
-+  FLAG_RETURNS_128BITS	= 1 << (31-31), /* These go in cr7  */
-+  FLAG_RETURNS_NOTHING	= 1 << (31-30),
-+  FLAG_RETURNS_FP	= 1 << (31-29),
-+  FLAG_RETURNS_64BITS	= 1 << (31-28),
-+
-+  FLAG_RETURNS_STRUCT	= 1 << (31-27), /* This goes in cr6  */
- 
-   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
-   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
-   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
-   FLAG_RETVAL_REFERENCE = 1 << (31- 4)
- };
- 
- /* About the DARWIN ABI.  */
- enum {
-   NUM_GPR_ARG_REGISTERS = 8,
--  NUM_FPR_ARG_REGISTERS = 13
-+  NUM_FPR_ARG_REGISTERS = 13,
-+  LINKAGE_AREA_GPRS = 6
- };
--enum { ASM_NEEDS_REGISTERS = 4 };
-+
-+enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */
- 
- /* ffi_prep_args is called by the assembly routine once stack space
-    has been allocated for the function's arguments.
-+   
-+   m32/m64
- 
-    The stack layout we want looks like this:
- 
-    |   Return address from ffi_call_DARWIN      |	higher addresses
-    |--------------------------------------------|
--   |   Previous backchain pointer	4	|	stack pointer here
-+   |   Previous backchain pointer	4/8	|	stack pointer here
-    |--------------------------------------------|<+ <<<	on entry to
--   |   Saved r28-r31			4*4	| |	ffi_call_DARWIN
-+   |   ASM_NEEDS_REGISTERS=r28-r31   4*(4/8)	| |	ffi_call_DARWIN
-    |--------------------------------------------| |
--   |   Parameters             (at least 8*4=32) | |
-+   |   When we have any FP activity... the	| |
-+   |   FPRs occupy NUM_FPR_ARG_REGISTERS slots	| |
-+   |   here fp13 .. fp1 from high to low addr.	| |
-+   ~						~ ~
-+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
-    |--------------------------------------------| |
--   |   Space for GPR2                   4       | |
-+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
-    |--------------------------------------------| |	stack	|
--   |   Reserved                       2*4       | |	grows	|
-+   |   Reserved                       2*4/8	| |	grows	|
-    |--------------------------------------------| |	down	V
--   |   Space for callee's LR		4	| |
-+   |   Space for callee's LR		4/8	| |
-    |--------------------------------------------| |	lower addresses
--   |   Saved CR                         4       | |
-+   |   Saved CR [low word for m64]      4/8	| |
-    |--------------------------------------------| |     stack pointer here
--   |   Current backchain pointer	4	|-/	during
-+   |   Current backchain pointer	4/8	|-/	during
-    |--------------------------------------------|   <<<	ffi_call_DARWIN
- 
-    */
- 
-+#if defined(POWERPC_DARWIN64)
-+static void
-+darwin64_pass_struct_by_value 
-+  (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **);
-+#endif
-+
-+/* This depends on GPR_SIZE = sizeof (unsigned long) */
-+
- void
- ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
- {
-   const unsigned bytes = ecif->cif->bytes;
-   const unsigned flags = ecif->cif->flags;
-   const unsigned nargs = ecif->cif->nargs;
-+#if !defined(POWERPC_DARWIN64) 
-   const ffi_abi abi = ecif->cif->abi;
-+#endif
- 
-   /* 'stacktop' points at the previous backchain pointer.  */
-   unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
- 
-   /* 'fpr_base' points at the space for fpr1, and grows upwards as
-      we use FPR registers.  */
-   double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
--  int fparg_count = 0;
--
-+  int gp_count = 0, fparg_count = 0;
- 
-   /* 'next_arg' grows up as we put parameters in it.  */
--  unsigned long *next_arg = stack + 6; /* 6 reserved positions.  */
-+  unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions.  */
- 
-   int i;
-   double double_tmp;
-   void **p_argv = ecif->avalue;
-   unsigned long gprvalue;
-   ffi_type** ptr = ecif->cif->arg_types;
-+#if !defined(POWERPC_DARWIN64) 
-   char *dest_cpy;
-+#endif
-   unsigned size_al = 0;
- 
-   /* Check that everything starts aligned properly.  */
-   FFI_ASSERT(((unsigned) (char *) stack & 0xF) == 0);
-   FFI_ASSERT(((unsigned) (char *) stacktop & 0xF) == 0);
-   FFI_ASSERT((bytes & 0xF) == 0);
- 
-   /* Deal with return values that are actually pass-by-reference.
-@@ -125,78 +150,95 @@ ffi_prep_args (extended_cif *ecif, unsig
-     {
-       switch ((*ptr)->type)
- 	{
- 	/* If a floating-point parameter appears before all of the general-
- 	   purpose registers are filled, the corresponding GPRs that match
- 	   the size of the floating-point parameter are skipped.  */
- 	case FFI_TYPE_FLOAT:
- 	  double_tmp = *(float *) *p_argv;
--	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
--	    *(double *)next_arg = double_tmp;
--	  else
-+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
- 	    *fpr_base++ = double_tmp;
-+#if defined(POWERPC_DARWIN)
-+	  *(float *)next_arg = *(float *) *p_argv;
-+#else
-+	  *(double *)next_arg = double_tmp;
-+#endif
- 	  next_arg++;
-+	  gp_count++;
- 	  fparg_count++;
- 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
- 	  break;
- 
- 	case FFI_TYPE_DOUBLE:
- 	  double_tmp = *(double *) *p_argv;
--	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
--	    *(double *)next_arg = double_tmp;
--	  else
-+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
- 	    *fpr_base++ = double_tmp;
-+	  *(double *)next_arg = double_tmp;
- #ifdef POWERPC64
- 	  next_arg++;
-+	  gp_count++;
- #else
- 	  next_arg += 2;
-+	  gp_count += 2;
- #endif
- 	  fparg_count++;
- 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
- 	  break;
- 
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- 
- 	case FFI_TYPE_LONGDOUBLE:
--#ifdef POWERPC64
-+#  if defined(POWERPC64) && !defined(POWERPC_DARWIN64)
-+	  /* ??? This will exceed the regs count when the value starts at fp13
-+	     and it will not put the extra bit on the stack.  */
- 	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
- 	    *(long double *) fpr_base++ = *(long double *) *p_argv;
- 	  else
- 	    *(long double *) next_arg = *(long double *) *p_argv;
- 	  next_arg += 2;
- 	  fparg_count += 2;
--#else
-+#  else
- 	  double_tmp = ((double *) *p_argv)[0];
- 	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
- 	    *fpr_base++ = double_tmp;
--	  else
--	    *(double *) next_arg = double_tmp;
-+	  *(double *) next_arg = double_tmp;
-+#    if defined(POWERPC_DARWIN64)
-+	  next_arg++;
-+	  gp_count++;
-+#    else
- 	  next_arg += 2;
-+	  gp_count += 2;
-+#    endif
- 	  fparg_count++;
--
- 	  double_tmp = ((double *) *p_argv)[1];
- 	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
- 	    *fpr_base++ = double_tmp;
--	  else
--	    *(double *) next_arg = double_tmp;
-+	  *(double *) next_arg = double_tmp;
-+#    if defined(POWERPC_DARWIN64)
-+	  next_arg++;
-+	  gp_count++;
-+#    else
- 	  next_arg += 2;
-+	  gp_count += 2;
-+#    endif
- 	  fparg_count++;
--#endif
-+#  endif
- 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
- 	  break;
- #endif
- 	case FFI_TYPE_UINT64:
- 	case FFI_TYPE_SINT64:
- #ifdef POWERPC64
- 	  gprvalue = *(long long *) *p_argv;
- 	  goto putgpr;
- #else
- 	  *(long long *) next_arg = *(long long *) *p_argv;
- 	  next_arg += 2;
-+	  gp_count += 2;
- #endif
- 	  break;
- 	case FFI_TYPE_POINTER:
- 	  gprvalue = *(unsigned long *) *p_argv;
- 	  goto putgpr;
- 	case FFI_TYPE_UINT8:
- 	  gprvalue = *(unsigned char *) *p_argv;
- 	  goto putgpr;
-@@ -206,101 +248,373 @@ ffi_prep_args (extended_cif *ecif, unsig
- 	case FFI_TYPE_UINT16:
- 	  gprvalue = *(unsigned short *) *p_argv;
- 	  goto putgpr;
- 	case FFI_TYPE_SINT16:
- 	  gprvalue = *(signed short *) *p_argv;
- 	  goto putgpr;
- 
- 	case FFI_TYPE_STRUCT:
--#ifdef POWERPC64
--	  dest_cpy = (char *) next_arg;
- 	  size_al = (*ptr)->size;
--	  if ((*ptr)->elements[0]->type == 3)
--	    size_al = ALIGN((*ptr)->size, 8);
--	  if (size_al < 3 && abi == FFI_DARWIN)
--	    dest_cpy += 4 - size_al;
--
--	  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
--	  next_arg += (size_al + 7) / 8;
-+#if defined(POWERPC_DARWIN64)
-+	  next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment);
-+	  darwin64_pass_struct_by_value (*ptr, (char *) *p_argv, 
-+					 (unsigned) size_al,
-+					 (unsigned int *) &fparg_count,
-+					 &fpr_base, &next_arg);
- #else
- 	  dest_cpy = (char *) next_arg;
- 
-+	  /* If the first member of the struct is a double, then include enough
-+	     padding in the struct size to align it to double-word.  */
-+	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
-+	    size_al = ALIGN((*ptr)->size, 8);
-+
-+#  if defined(POWERPC64) 
-+	  FFI_ASSERT (abi != FFI_DARWIN);
-+	  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
-+	  next_arg += (size_al + 7) / 8;
-+#  else
- 	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
- 	     SI 4 bytes) are aligned as if they were those modes.
- 	     Structures with 3 byte in size are padded upwards.  */
--	  size_al = (*ptr)->size;
--	  /* If the first member of the struct is a double, then align
--	     the struct to double-word.  */
--	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
--	    size_al = ALIGN((*ptr)->size, 8);
- 	  if (size_al < 3 && abi == FFI_DARWIN)
- 	    dest_cpy += 4 - size_al;
- 
- 	  memcpy((char *) dest_cpy, (char *) *p_argv, size_al);
- 	  next_arg += (size_al + 3) / 4;
-+#  endif
- #endif
- 	  break;
- 
- 	case FFI_TYPE_INT:
- 	case FFI_TYPE_SINT32:
- 	  gprvalue = *(signed int *) *p_argv;
- 	  goto putgpr;
- 
- 	case FFI_TYPE_UINT32:
- 	  gprvalue = *(unsigned int *) *p_argv;
- 	putgpr:
- 	  *next_arg++ = gprvalue;
-+	  gp_count++;
- 	  break;
- 	default:
- 	  break;
- 	}
-     }
- 
-   /* Check that we didn't overrun the stack...  */
-   //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
-   //FFI_ASSERT((unsigned *)fpr_base
-   //	     <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
-   //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
- }
- 
-+#if defined(POWERPC_DARWIN64)
-+
-+/* See if we can put some of the struct into fprs.
-+   This should not be called for structures of size 16 bytes, since these are not
-+   broken out this way.  */
-+static void
-+darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr)
-+{
-+  int i;
-+
-+  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
-+
-+  for (i = 0; s->elements[i] != NULL; i++)
-+    {
-+      ffi_type *p = s->elements[i];
-+      switch (p->type)
-+	{
-+	  case FFI_TYPE_STRUCT:
-+	    darwin64_scan_struct_for_floats (p, nfpr);
-+	    break;
-+	  case FFI_TYPE_LONGDOUBLE:
-+	    (*nfpr) += 2;
-+	    break;
-+	  case FFI_TYPE_DOUBLE:
-+	  case FFI_TYPE_FLOAT:
-+	    (*nfpr) += 1;
-+	    break;
-+	  default:
-+	    break;    
-+	}
-+    }
-+}
-+
-+static int
-+darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr)
-+{
-+  unsigned struct_offset=0, i;
-+
-+  for (i = 0; s->elements[i] != NULL; i++)
-+    {
-+      char *item_base;
-+      ffi_type *p = s->elements[i];
-+      /* Find the start of this item (0 for the first one).  */
-+      if (i > 0)
-+        struct_offset = ALIGN(struct_offset, p->alignment);
-+
-+      item_base = src + struct_offset;
-+
-+      switch (p->type)
-+	{
-+	  case FFI_TYPE_STRUCT:
-+	    if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))
-+	      return 1;
-+	    break;
-+	  case FFI_TYPE_LONGDOUBLE:
-+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
-+	      return 1;
-+	    (*nfpr) += 1;
-+	    item_base += 8;
-+	  /* FALL THROUGH */
-+	  case FFI_TYPE_DOUBLE:
-+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
-+	      return 1;
-+	    (*nfpr) += 1;
-+	    break;
-+	  case FFI_TYPE_FLOAT:
-+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
-+	      return 1;
-+	    (*nfpr) += 1;
-+	    break;
-+	  default:
-+	    /* If we try and place any item, that is non-float, once we've
-+	       exceeded the 8 GPR mark, then we can't fit the struct.  */
-+	    if ((unsigned long)item_base >= 8*8) 
-+	      return 1;
-+	    break;    
-+	}
-+      /* now count the size of what we just used.  */
-+      struct_offset += p->size;
-+    }
-+  return 0;
-+}
-+
-+/* Can this struct be returned by value?  */
-+int 
-+darwin64_struct_ret_by_value_p (ffi_type *s)
-+{
-+  unsigned nfp = 0;
-+
-+  FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT);
-+  
-+  /* The largest structure we can return is 8long + 13 doubles.  */
-+  if (s->size > 168)
-+    return 0;
-+  
-+  /* We can't pass more than 13 floats.  */
-+  darwin64_scan_struct_for_floats (s, &nfp);
-+  if (nfp > 13)
-+    return 0;
-+  
-+  /* If there are not too many floats, and the struct is
-+     small enough to accommodate in the GPRs, then it must be OK.  */
-+  if (s->size <= 64)
-+    return 1;
-+  
-+  /* Well, we have to look harder.  */
-+  nfp = 0;
-+  if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp))
-+    return 0;
-+  
-+  return 1;
-+}
-+
-+void
-+darwin64_pass_struct_floats (ffi_type *s, char *src, 
-+			     unsigned *nfpr, double **fprs)
-+{
-+  int i;
-+  double *fpr_base = *fprs;
-+  unsigned struct_offset = 0;
-+
-+  /* We don't assume anything about the alignment of the source.  */
-+  for (i = 0; s->elements[i] != NULL; i++)
-+    {
-+      char *item_base;
-+      ffi_type *p = s->elements[i];
-+      /* Find the start of this item (0 for the first one).  */
-+      if (i > 0)
-+        struct_offset = ALIGN(struct_offset, p->alignment);
-+      item_base = src + struct_offset;
-+
-+      switch (p->type)
-+	{
-+	  case FFI_TYPE_STRUCT:
-+	    darwin64_pass_struct_floats (p, item_base, nfpr,
-+					   &fpr_base);
-+	    break;
-+	  case FFI_TYPE_LONGDOUBLE:
-+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
-+	      *fpr_base++ = *(double *)item_base;
-+	    (*nfpr) += 1;
-+	    item_base += 8;
-+	  /* FALL THROUGH */
-+	  case FFI_TYPE_DOUBLE:
-+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
-+	      *fpr_base++ = *(double *)item_base;
-+	    (*nfpr) += 1;
-+	    break;
-+	  case FFI_TYPE_FLOAT:
-+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
-+	      *fpr_base++ = (double) *(float *)item_base;
-+	    (*nfpr) += 1;
-+	    break;
-+	  default:
-+	    break;    
-+	}
-+      /* now count the size of what we just used.  */
-+      struct_offset += p->size;
-+    }
-+  /* Update the scores.  */
-+  *fprs = fpr_base;
-+}
-+
-+/* Darwin64 special rules.
-+   Break out a struct into params and float registers.  */
-+static void
-+darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size,
-+			       unsigned *nfpr, double **fprs, unsigned long **arg)
-+{
-+  unsigned long *next_arg = *arg;
-+  char *dest_cpy = (char *)next_arg;
-+
-+  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
-+
-+  if (!size)
-+    return;
-+
-+  /* First... special cases.  */
-+  if (size < 3
-+      || (size == 4 
-+	  && s->elements[0] 
-+	  && s->elements[0]->type != FFI_TYPE_FLOAT))
-+    {
-+      /* Must be at least one GPR, padding is unspecified in value, 
-+	 let's make it zero.  */
-+      *next_arg = 0UL; 
-+      dest_cpy += 8 - size;
-+      memcpy ((char *) dest_cpy, src, size);
-+      next_arg++;
-+    }
-+  else if (size == 16)
-+    {
-+      memcpy ((char *) dest_cpy, src, size);
-+      next_arg += 2;
-+    }
-+  else
-+    {
-+      /* now the general case, we consider embedded floats.  */
-+      memcpy ((char *) dest_cpy, src, size);
-+      darwin64_pass_struct_floats (s, src, nfpr, fprs);
-+      next_arg += (size+7)/8;
-+    }
-+    
-+  *arg = next_arg;
-+}
-+
-+double *
-+darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf)
-+{
-+  int i;
-+  unsigned struct_offset = 0;
-+
-+  /* We don't assume anything about the alignment of the source.  */
-+  for (i = 0; s->elements[i] != NULL; i++)
-+    {
-+      char *item_base;
-+      ffi_type *p = s->elements[i];
-+      /* Find the start of this item (0 for the first one).  */
-+      if (i > 0)
-+        struct_offset = ALIGN(struct_offset, p->alignment);
-+      item_base = dest + struct_offset;
-+
-+      switch (p->type)
-+	{
-+	  case FFI_TYPE_STRUCT:
-+	    fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);
-+	    break;
-+	  case FFI_TYPE_LONGDOUBLE:
-+	    if (*nf < NUM_FPR_ARG_REGISTERS)
-+	      {
-+		*(double *)item_base = *fprs++ ;
-+		(*nf) += 1;
-+	      }
-+	    item_base += 8;
-+	  /* FALL THROUGH */
-+	  case FFI_TYPE_DOUBLE:
-+	    if (*nf < NUM_FPR_ARG_REGISTERS)
-+	      {
-+		*(double *)item_base = *fprs++ ;
-+		(*nf) += 1;
-+	      }
-+	    break;
-+	  case FFI_TYPE_FLOAT:
-+	    if (*nf < NUM_FPR_ARG_REGISTERS)
-+	      {
-+		*(float *)item_base = (float) *fprs++ ;
-+		(*nf) += 1;
-+	      }
-+	    break;
-+	  default:
-+	    break;    
-+	}
-+      /* now count the size of what we just used.  */
-+      struct_offset += p->size;
-+    }
-+  return fprs;
-+}
-+
-+#endif
-+
- /* Adjust the size of S to be correct for Darwin.
--   On Darwin, the first field of a structure has natural alignment.  */
-+   On Darwin m32, the first field of a structure has natural alignment.  
-+   On Darwin m64, all fields have natural alignment.  */
- 
- static void
- darwin_adjust_aggregate_sizes (ffi_type *s)
- {
-   int i;
- 
-   if (s->type != FFI_TYPE_STRUCT)
-     return;
- 
-   s->size = 0;
-   for (i = 0; s->elements[i] != NULL; i++)
-     {
-       ffi_type *p;
-       int align;
-       
-       p = s->elements[i];
--      darwin_adjust_aggregate_sizes (p);
--      if (i == 0
--	  && (p->type == FFI_TYPE_UINT64
--	      || p->type == FFI_TYPE_SINT64
--	      || p->type == FFI_TYPE_DOUBLE
--	      || p->alignment == 8))
--	align = 8;
-+      if (p->type == FFI_TYPE_STRUCT)
-+	darwin_adjust_aggregate_sizes (p);
-+#if defined(POWERPC_DARWIN64)
-+      /* Natural alignment for all items.  */
-+      align = p->alignment;
-+#else
-+      /* Natrual alignment for the first item... */
-+      if (i == 0)
-+	align = p->alignment;
-       else if (p->alignment == 16 || p->alignment < 4)
-+	/* .. subsequent items with vector or align < 4 have natural align.  */
- 	align = p->alignment;
-       else
-+	/* .. or align is 4.  */
- 	align = 4;
-+#endif
-+      /* Pad, if necessary, before adding the current item.  */
-       s->size = ALIGN(s->size, align) + p->size;
-     }
-   
-   s->size = ALIGN(s->size, s->alignment);
-   
-+  /* This should not be necessary on m64, but harmless.  */
-   if (s->elements[0]->type == FFI_TYPE_UINT64
-       || s->elements[0]->type == FFI_TYPE_SINT64
-       || s->elements[0]->type == FFI_TYPE_DOUBLE
-       || s->elements[0]->alignment == 8)
-     s->alignment = s->alignment > 8 ? s->alignment : 8;
-   /* Do not add additional tail padding.  */
- }
- 
-@@ -342,17 +656,17 @@ aix_adjust_aggregate_sizes (ffi_type *s)
- /* Perform machine dependent cif processing.  */
- ffi_status
- ffi_prep_cif_machdep (ffi_cif *cif)
- {
-   /* All this is for the DARWIN ABI.  */
-   unsigned i;
-   ffi_type **ptr;
-   unsigned bytes;
--  int fparg_count = 0, intarg_count = 0;
-+  unsigned fparg_count = 0, intarg_count = 0;
-   unsigned flags = 0;
-   unsigned size_al = 0;
- 
-   /* All the machine-independent calculation of cif->bytes will be wrong.
-      All the calculation of structure sizes will also be wrong.
-      Redo the calculation for DARWIN.  */
- 
-   if (cif->abi == FFI_DARWIN)
-@@ -367,26 +681,35 @@ ffi_prep_cif_machdep (ffi_cif *cif)
-       aix_adjust_aggregate_sizes (cif->rtype);
-       for (i = 0; i < cif->nargs; i++)
- 	aix_adjust_aggregate_sizes (cif->arg_types[i]);
-     }
- 
-   /* Space for the frame pointer, callee's LR, CR, etc, and for
-      the asm's temp regs.  */
- 
--  bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
-+  bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long);
- 
--  /* Return value handling.  The rules are as follows:
-+  /* Return value handling.  
-+    The rules m32 are as follows:
-      - 32-bit (or less) integer values are returned in gpr3;
--     - Structures of size <= 4 bytes also returned in gpr3;
--     - 64-bit integer values and structures between 5 and 8 bytes are returned
--       in gpr3 and gpr4;
-+     - structures of size <= 4 bytes also returned in gpr3;
-+     - 64-bit integer values [??? and structures between 5 and 8 bytes] are
-+       returned in gpr3 and gpr4;
-      - Single/double FP values are returned in fpr1;
-      - Long double FP (if not equivalent to double) values are returned in
-        fpr1 and fpr2;
-+     m64:
-+     - 64-bit or smaller integral values are returned in GPR3
-+     - Single/double FP values are returned in fpr1;
-+     - Long double FP values are returned in fpr1 and fpr2;
-+     m64 Structures:
-+     - If the structure could be accommodated in registers were it to be the
-+       first argument to a routine, then it is returned in those registers.
-+     m32/m64 structures otherwise:
-      - Larger structures values are allocated space and a pointer is passed
-        as the first argument.  */
-   switch (cif->rtype->type)
-     {
- 
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-     case FFI_TYPE_LONGDOUBLE:
-       flags |= FLAG_RETURNS_128BITS;
-@@ -405,124 +728,193 @@ ffi_prep_cif_machdep (ffi_cif *cif)
-     case FFI_TYPE_SINT64:
- #ifdef POWERPC64
-     case FFI_TYPE_POINTER:
- #endif
-       flags |= FLAG_RETURNS_64BITS;
-       break;
- 
-     case FFI_TYPE_STRUCT:
-+#if defined(POWERPC_DARWIN64)
-+      {
-+	/* Can we fit the struct into regs?  */
-+	if (darwin64_struct_ret_by_value_p (cif->rtype))
-+	  {
-+	    unsigned nfpr = 0;
-+	    flags |= FLAG_RETURNS_STRUCT;
-+	    if (cif->rtype->size != 16)
-+	      darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;
-+	    else
-+	      flags |= FLAG_RETURNS_128BITS;
-+	    /* Will be 0 for 16byte struct.  */
-+	    if (nfpr)
-+	      flags |= FLAG_RETURNS_FP;
-+	  }
-+	else /* By ref. */
-+	  {
-+	    flags |= FLAG_RETVAL_REFERENCE;
-+	    flags |= FLAG_RETURNS_NOTHING;
-+	    intarg_count++;
-+	  }
-+      }
-+#elif defined(DARWIN_PPC)
-+      if (cif->rtype->size <= 4)
-+	flags |= FLAG_RETURNS_STRUCT;
-+      else /* else by reference.  */
-+	{
-+	  flags |= FLAG_RETVAL_REFERENCE;
-+	  flags |= FLAG_RETURNS_NOTHING;
-+	  intarg_count++;
-+	}
-+#else /* assume we pass by ref.  */
-       flags |= FLAG_RETVAL_REFERENCE;
-       flags |= FLAG_RETURNS_NOTHING;
-       intarg_count++;
-+#endif
-       break;
-     case FFI_TYPE_VOID:
-       flags |= FLAG_RETURNS_NOTHING;
-       break;
- 
-     default:
-       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
-       break;
-     }
- 
-   /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
-      first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
--     goes on the stack.  Structures are passed as a pointer to a copy of
--     the structure. Stuff on the stack needs to keep proper alignment.  */
-+     goes on the stack.  
-+     ??? Structures are passed as a pointer to a copy of the structure. 
-+     Stuff on the stack needs to keep proper alignment.  
-+     For m64 the count is effectively of half-GPRs.  */
-   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
-     {
-+      unsigned align_words;
-       switch ((*ptr)->type)
- 	{
- 	case FFI_TYPE_FLOAT:
- 	case FFI_TYPE_DOUBLE:
- 	  fparg_count++;
-+#if !defined(POWERPC_DARWIN64)
- 	  /* If this FP arg is going on the stack, it must be
- 	     8-byte-aligned.  */
- 	  if (fparg_count > NUM_FPR_ARG_REGISTERS
--	      && intarg_count%2 != 0)
-+	      && (intarg_count & 0x01) != 0)
- 	    intarg_count++;
-+#endif
- 	  break;
- 
- #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
--
- 	case FFI_TYPE_LONGDOUBLE:
- 	  fparg_count += 2;
- 	  /* If this FP arg is going on the stack, it must be
--	     8-byte-aligned.  */
--	  if (fparg_count > NUM_FPR_ARG_REGISTERS
--	      && intarg_count%2 != 0)
--	    intarg_count++;
--	  intarg_count +=2;
-+	     16-byte-aligned.  */
-+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
-+#if defined (POWERPC64)
-+	    intarg_count = ALIGN(intarg_count, 2);
-+#else
-+	    intarg_count = ALIGN(intarg_count, 4);
-+#endif
- 	  break;
- #endif
- 
- 	case FFI_TYPE_UINT64:
- 	case FFI_TYPE_SINT64:
-+#if defined(POWERPC64)
-+	  intarg_count++;
-+#else
- 	  /* 'long long' arguments are passed as two words, but
- 	     either both words must fit in registers or both go
- 	     on the stack.  If they go on the stack, they must
- 	     be 8-byte-aligned.  */
- 	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
--	      || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
-+	      || (intarg_count >= NUM_GPR_ARG_REGISTERS 
-+	          && (intarg_count & 0x01) != 0))
- 	    intarg_count++;
- 	  intarg_count += 2;
-+#endif
- 	  break;
- 
- 	case FFI_TYPE_STRUCT:
- 	  size_al = (*ptr)->size;
-+#if defined(POWERPC_DARWIN64)
-+	  align_words = (*ptr)->alignment >> 3;
-+	  if (align_words)
-+	    intarg_count = ALIGN(intarg_count, align_words);
-+	  /* Base size of the struct.  */
-+	  intarg_count += (size_al + 7) / 8;
-+	  /* If 16 bytes then don't worry about floats.  */
-+	  if (size_al != 16)
-+	    /* Scan through for floats to be placed in regs.  */
-+	    darwin64_scan_struct_for_floats (*ptr, &fparg_count) ;
-+#else
-+	  align_words = (*ptr)->alignment >> 2;
-+	  if (align_words)
-+	    intarg_count = ALIGN(intarg_count, align_words);
- 	  /* If the first member of the struct is a double, then align
--	     the struct to double-word.  */
-+	     the struct to double-word. 
- 	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
--	    size_al = ALIGN((*ptr)->size, 8);
--#ifdef POWERPC64
-+	    size_al = ALIGN((*ptr)->size, 8); */
-+#  ifdef POWERPC64
- 	  intarg_count += (size_al + 7) / 8;
--#else
-+#  else
- 	  intarg_count += (size_al + 3) / 4;
-+#  endif
- #endif
- 	  break;
- 
- 	default:
- 	  /* Everything else is passed as a 4-byte word in a GPR, either
- 	     the object itself or a pointer to it.  */
- 	  intarg_count++;
- 	  break;
- 	}
-     }
- 
-   if (fparg_count != 0)
-     flags |= FLAG_FP_ARGUMENTS;
- 
-+#if defined(POWERPC_DARWIN64)
-+  /* Space to image the FPR registers, if needed - which includes when they might be
-+     used in a struct return.  */
-+  if (fparg_count != 0 
-+      || ((flags & FLAG_RETURNS_STRUCT)
-+	   && (flags & FLAG_RETURNS_FP)))
-+    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
-+#else
-   /* Space for the FPR registers, if needed.  */
-   if (fparg_count != 0)
-     bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
-+#endif
- 
-   /* Stack space.  */
- #ifdef POWERPC64
-   if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
-     bytes += (intarg_count + fparg_count) * sizeof(long);
- #else
-   if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
-     bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
- #endif
-   else
-     bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
- 
-   /* The stack space allocated needs to be a multiple of 16 bytes.  */
--  bytes = (bytes + 15) & ~0xF;
-+  bytes = ALIGN(bytes, 16) ;
- 
-   cif->flags = flags;
-   cif->bytes = bytes;
- 
-   return FFI_OK;
- }
- 
- extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
- 			 void (*fn)(void), void (*fn2)(void));
-+
- extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
--			    void (*fn)(void), void (*fn2)(void));
-+			    void (*fn)(void), void (*fn2)(void), ffi_type*);
- 
- void
- ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
- {
-   extended_cif ecif;
- 
-   ecif.cif = cif;
-   ecif.avalue = avalue;
-@@ -541,17 +933,17 @@ ffi_call (ffi_cif *cif, void (*fn)(void)
-   switch (cif->abi)
-     {
-     case FFI_AIX:
-       ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
- 		   FFI_FN(ffi_prep_args));
-       break;
-     case FFI_DARWIN:
-       ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
--		      FFI_FN(ffi_prep_args));
-+		      FFI_FN(ffi_prep_args), cif->rtype);
-       break;
-     default:
-       FFI_ASSERT(0);
-       break;
-     }
- }
- 
- static void flush_icache(char *);
-@@ -561,123 +953,127 @@ static void flush_range(char *, int);
-    points to one of these.  */
- 
- typedef struct aix_fd_struct {
-   void *code_pointer;
-   void *toc;
- } aix_fd;
- 
- /* here I'd like to add the stack frame layout we use in darwin_closure.S
--   and aix_clsoure.S
-+   and aix_closure.S
- 
--   SP previous -> +---------------------------------------+ <--- child frame
--		  | back chain to caller 4                |
--		  +---------------------------------------+ 4
--		  | saved CR 4                            |
--		  +---------------------------------------+ 8
--		  | saved LR 4                            |
--		  +---------------------------------------+ 12
--		  | reserved for compilers 4              |
--		  +---------------------------------------+ 16
--		  | reserved for binders 4                |
--		  +---------------------------------------+ 20
--		  | saved TOC pointer 4                   |
--		  +---------------------------------------+ 24
--		  | always reserved 8*4=32 (previous GPRs)|
--		  | according to the linkage convention   |
--		  | from AIX                              |
--		  +---------------------------------------+ 56
--		  | our FPR area 13*8=104                 |
--		  | f1                                    |
--		  | .                                     |
--		  | f13                                   |
--		  +---------------------------------------+ 160
--		  | result area 8                         |
--		  +---------------------------------------+ 168
--		  | alignement to the next multiple of 16 |
--SP current -->    +---------------------------------------+ 176 <- parent frame
--		  | back chain to caller 4                |
--		  +---------------------------------------+ 180
--		  | saved CR 4                            |
--		  +---------------------------------------+ 184
--		  | saved LR 4                            |
--		  +---------------------------------------+ 188
--		  | reserved for compilers 4              |
--		  +---------------------------------------+ 192
--		  | reserved for binders 4                |
--		  +---------------------------------------+ 196
--		  | saved TOC pointer 4                   |
--		  +---------------------------------------+ 200
--		  | always reserved 8*4=32  we store our  |
--		  | GPRs here                             |
--		  | r3                                    |
--		  | .                                     |
--		  | r10                                   |
--		  +---------------------------------------+ 232
--		  | overflow part                         |
--		  +---------------------------------------+ xxx
--		  | ????                                  |
--		  +---------------------------------------+ xxx
-+   m32/m64
-+
-+   The stack layout looks like this:
-+
-+   |   Additional params...			| |     Higher address
-+   ~						~ ~
-+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
-+   |--------------------------------------------| |
-+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
-+   |--------------------------------------------| |
-+   |   Reserved                       2*4/8	| |
-+   |--------------------------------------------| |
-+   |   Space for callee's LR		4/8	| |
-+   |--------------------------------------------| |
-+   |   Saved CR [low word for m64]      4/8	| |
-+   |--------------------------------------------| |
-+   |   Current backchain pointer	4/8	|-/ Parent's frame.
-+   |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM
-+   |   Result Bytes			16	| |
-+   |--------------------------------------------| |
-+   ~   padding to 16-byte alignment		~ ~
-+   |--------------------------------------------| |
-+   |   NUM_FPR_ARG_REGISTERS slots		| |
-+   |   here fp13 .. fp1		       13*8	| |
-+   |--------------------------------------------| |
-+   |   R3..R10			  8*4/8=32/64	| | NUM_GPR_ARG_REGISTERS
-+   |--------------------------------------------| |
-+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
-+   |--------------------------------------------| |	stack	|
-+   |   Reserved [compiler,binder]     2*4/8	| |	grows	|
-+   |--------------------------------------------| |	down	V
-+   |   Space for callee's LR		4/8	| |
-+   |--------------------------------------------| |	lower addresses
-+   |   Saved CR [low word for m64]      4/8	| |
-+   |--------------------------------------------| |     stack pointer here
-+   |   Current backchain pointer	4/8	|-/	during
-+   |--------------------------------------------|   <<<	ffi_closure_ASM.
- 
- */
-+
- ffi_status
- ffi_prep_closure_loc (ffi_closure* closure,
- 		      ffi_cif* cif,
- 		      void (*fun)(ffi_cif*, void*, void**, void*),
- 		      void *user_data,
- 		      void *codeloc)
- {
-   unsigned int *tramp;
-   struct ffi_aix_trampoline_struct *tramp_aix;
-   aix_fd *fd;
- 
-   switch (cif->abi)
-     {
--    case FFI_DARWIN:
-+      case FFI_DARWIN:
- 
--      FFI_ASSERT (cif->abi == FFI_DARWIN);
-+	FFI_ASSERT (cif->abi == FFI_DARWIN);
- 
--      tramp = (unsigned int *) &closure->tramp[0];
--      tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
--      tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
--      tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
--      tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
--      tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
--      tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
--      tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
--      tramp[9] = 0x4e800420;  /*   bctr  */
--      tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
--      tramp[3] = (unsigned long) codeloc; /* context  */
-+	tramp = (unsigned int *) &closure->tramp[0];
-+#if defined(POWERPC_DARWIN64)
-+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
-+	tramp[1] = 0x429f0015;  /*   bcl-    20,4*cr7+so,  +0x18 (L1)  */
-+	/* We put the addresses here.  */
-+	tramp[6] = 0x7d6802a6;  /*L1:   mflr    r11  */
-+	tramp[7] = 0xe98b0000;  /*   ld     r12,0(r11) function address  */
-+	tramp[8] = 0x7c0803a6;  /*   mtlr    r0   */
-+	tramp[9] = 0x7d8903a6;  /*   mtctr   r12  */
-+	tramp[10] = 0xe96b0008;  /*   lwz     r11,8(r11) static chain  */
-+	tramp[11] = 0x4e800420;  /*   bctr  */
- 
--      closure->cif = cif;
--      closure->fun = fun;
--      closure->user_data = user_data;
-+	*((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function  */
-+	*((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context  */
-+#else
-+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
-+	tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
-+	tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
-+	tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
-+	tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
-+	tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
-+	tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
-+	tramp[9] = 0x4e800420;  /*   bctr  */
-+	tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
-+	tramp[3] = (unsigned long) codeloc; /* context  */
-+#endif
-+	closure->cif = cif;
-+	closure->fun = fun;
-+	closure->user_data = user_data;
- 
--      /* Flush the icache. Only necessary on Darwin.  */
--      flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
-+	/* Flush the icache. Only necessary on Darwin.  */
-+	flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
- 
--      break;
-+	break;
- 
-     case FFI_AIX:
- 
-       tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
-       fd = (aix_fd *)(void *)ffi_closure_ASM;
- 
-       FFI_ASSERT (cif->abi == FFI_AIX);
- 
-       tramp_aix->code_pointer = fd->code_pointer;
-       tramp_aix->toc = fd->toc;
-       tramp_aix->static_chain = codeloc;
-       closure->cif = cif;
-       closure->fun = fun;
-       closure->user_data = user_data;
-+      break;
- 
-     default:
--
--      FFI_ASSERT(0);
-+      return FFI_BAD_ABI;
-       break;
-     }
-   return FFI_OK;
- }
- 
- static void
- flush_icache(char *addr)
- {
-@@ -703,28 +1099,28 @@ flush_range(char * addr1, int size)
- }
- 
- typedef union
- {
-   float f;
-   double d;
- } ffi_dblfl;
- 
--int
-+ffi_type *
- ffi_closure_helper_DARWIN (ffi_closure *, void *,
- 			   unsigned long *, ffi_dblfl *);
- 
- /* Basically the trampoline invokes ffi_closure_ASM, and on
-    entry, r11 holds the address of the closure.
-    After storing the registers that could possibly contain
-    parameters to be passed into the stack frame and setting
-    up space for a return value, ffi_closure_ASM invokes the
-    following helper function to do most of the work.  */
- 
--int
-+ffi_type *
- ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
- 			   unsigned long *pgr, ffi_dblfl *pfr)
- {
-   /* rvalue is the pointer to space for return value in closure assembly
-      pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
-      pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
- 
-   typedef double ldbits[2];
-@@ -736,97 +1132,132 @@ ffi_closure_helper_DARWIN (ffi_closure *
-   };
- 
-   void **          avalue;
-   ffi_type **      arg_types;
-   long             i, avn;
-   ffi_cif *        cif;
-   ffi_dblfl *      end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
-   unsigned         size_al;
-+#if defined(POWERPC_DARWIN64)
-+  unsigned 	   fpsused = 0;
-+#endif
- 
-   cif = closure->cif;
-   avalue = alloca (cif->nargs * sizeof(void *));
- 
--  /* Copy the caller's structure return value address so that the closure
--     returns the data directly to the caller.  */
-   if (cif->rtype->type == FFI_TYPE_STRUCT)
-     {
-+#if defined(POWERPC_DARWIN64)
-+      if (!darwin64_struct_ret_by_value_p (cif->rtype))
-+	{
-+    	  /* Won't fit into the regs - return by ref.  */
-+	  rvalue = (void *) *pgr;
-+	  pgr++;
-+	}
-+#elif defined(DARWIN_PPC)
-+      if (cif->rtype->size > 4)
-+	{
-+	  rvalue = (void *) *pgr;
-+	  pgr++;
-+	}
-+#else /* assume we return by ref.  */
-       rvalue = (void *) *pgr;
-       pgr++;
-+#endif
-     }
- 
-   i = 0;
-   avn = cif->nargs;
-   arg_types = cif->arg_types;
- 
-   /* Grab the addresses of the arguments from the stack frame.  */
-   while (i < avn)
-     {
-       switch (arg_types[i]->type)
- 	{
- 	case FFI_TYPE_SINT8:
- 	case FFI_TYPE_UINT8:
--#ifdef POWERPC64
-+#if  defined(POWERPC64)
- 	  avalue[i] = (char *) pgr + 7;
- #else
- 	  avalue[i] = (char *) pgr + 3;
- #endif
- 	  pgr++;
- 	  break;
- 
- 	case FFI_TYPE_SINT16:
- 	case FFI_TYPE_UINT16:
--#ifdef POWERPC64
-+#if  defined(POWERPC64)
- 	  avalue[i] = (char *) pgr + 6;
- #else
- 	  avalue[i] = (char *) pgr + 2;
- #endif
- 	  pgr++;
- 	  break;
- 
- 	case FFI_TYPE_SINT32:
- 	case FFI_TYPE_UINT32:
--#ifdef POWERPC64
-+#if  defined(POWERPC64)
- 	  avalue[i] = (char *) pgr + 4;
- #else
- 	case FFI_TYPE_POINTER:
- 	  avalue[i] = pgr;
- #endif
- 	  pgr++;
- 	  break;
- 
- 	case FFI_TYPE_STRUCT:
--#ifdef POWERPC64
- 	  size_al = arg_types[i]->size;
--	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
--	    size_al = ALIGN (arg_types[i]->size, 8);
--	  if (size_al < 3 && cif->abi == FFI_DARWIN)
--	    avalue[i] = (char *) pgr + 8 - size_al;
--	  else
--	    avalue[i] = pgr;
-+#if defined(POWERPC_DARWIN64)
-+	  pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment);
-+	  if (size_al < 3 || size_al == 4)
-+	    {
-+	      avalue[i] = ((char *)pgr)+8-size_al;
-+	      if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT
-+		  && fpsused < NUM_FPR_ARG_REGISTERS)
-+		{
-+		  *(float *)pgr = (float) *(double *)pfr;
-+		  pfr++;
-+		  fpsused++;
-+		}
-+	    }
-+	  else 
-+	    {
-+	      if (size_al != 16)
-+		pfr = (ffi_dblfl *) 
-+		    darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr,
-+						   (double *)pfr, &fpsused);
-+	      avalue[i] = pgr;
-+	    }
- 	  pgr += (size_al + 7) / 8;
- #else
--	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
--	     SI 4 bytes) are aligned as if they were those modes.  */
--	  size_al = arg_types[i]->size;
- 	  /* If the first member of the struct is a double, then align
- 	     the struct to double-word.  */
- 	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
- 	    size_al = ALIGN(arg_types[i]->size, 8);
-+#  if defined(POWERPC64)
-+	  FFI_ASSERT (cif->abi != FFI_DARWIN);
-+	  avalue[i] = pgr;
-+	  pgr += (size_al + 7) / 8;
-+#  else
-+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
-+	     SI 4 bytes) are aligned as if they were those modes.  */
- 	  if (size_al < 3 && cif->abi == FFI_DARWIN)
- 	    avalue[i] = (char*) pgr + 4 - size_al;
- 	  else
- 	    avalue[i] = pgr;
- 	  pgr += (size_al + 3) / 4;
-+#  endif
- #endif
- 	  break;
- 
- 	case FFI_TYPE_SINT64:
- 	case FFI_TYPE_UINT64:
--#ifdef POWERPC64
-+#if  defined(POWERPC64)
- 	case FFI_TYPE_POINTER:
- 	  avalue[i] = pgr;
- 	  pgr++;
- 	  break;
- #else
- 	  /* Long long ints are passed in two gpr's.  */
- 	  avalue[i] = pgr;
- 	  pgr += 2;
-@@ -919,10 +1350,10 @@ ffi_closure_helper_DARWIN (ffi_closure *
- 	  FFI_ASSERT(0);
- 	}
-       i++;
-     }
- 
-   (closure->fun) (cif, rvalue, avalue, closure->user_data);
- 
-   /* Tell ffi_closure_ASM to perform return type promotions.  */
--  return cif->rtype->type;
-+  return cif->rtype;
- }
-diff --git a/js/src/ctypes/libffi/src/powerpc/ffitarget.h b/js/src/ctypes/libffi/src/powerpc/ffitarget.h
---- a/js/src/ctypes/libffi/src/powerpc/ffitarget.h
-+++ b/js/src/ctypes/libffi/src/powerpc/ffitarget.h
-@@ -1,11 +1,13 @@
- /* -----------------------------------------------------------------*-C-*-
--   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
--   Copyright (C) 2007, 2008 Free Software Foundation, Inc
-+   ffitarget.h - Copyright (c) 2012  Anthony Green
-+                 Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
-+                 Copyright (c) 1996-2003  Red Hat, Inc.
-+
-    Target configuration macros for PowerPC.
- 
-    Permission is hereby granted, free of charge, to any person obtaining
-    a copy of this software and associated documentation files (the
-    ``Software''), to deal in the Software without restriction, including
-    without limitation the rights to use, copy, modify, merge, publish,
-    distribute, sublicense, and/or sell copies of the Software, and to
-    permit persons to whom the Software is furnished to do so, subject to
-@@ -23,26 +25,33 @@
-    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-    DEALINGS IN THE SOFTWARE.
- 
-    ----------------------------------------------------------------------- */
- 
- #ifndef LIBFFI_TARGET_H
- #define LIBFFI_TARGET_H
- 
-+#ifndef LIBFFI_H
-+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
-+#endif
-+
- /* ---- System specific configurations ----------------------------------- */
- 
- #if defined (POWERPC) && defined (__powerpc64__)	/* linux64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
--#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin */
-+#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
-+#ifndef POWERPC_DARWIN64
-+#define POWERPC_DARWIN64
-+#endif
- #elif defined (POWERPC_AIX) && defined (__64BIT__)	/* AIX64 */
- #ifndef POWERPC64
- #define POWERPC64
- #endif
- #endif
- 
- #ifndef LIBFFI_ASM
- typedef unsigned long          ffi_arg;
-@@ -52,28 +61,24 @@ typedef enum ffi_abi {
-   FFI_FIRST_ABI = 0,
- 
- #ifdef POWERPC
-   FFI_SYSV,
-   FFI_GCC_SYSV,
-   FFI_LINUX64,
-   FFI_LINUX,
-   FFI_LINUX_SOFT_FLOAT,
--# ifdef POWERPC64
-+# if defined(POWERPC64)
-   FFI_DEFAULT_ABI = FFI_LINUX64,
-+# elif defined(__NO_FPRS__)
-+  FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
-+# elif (__LDBL_MANT_DIG__ == 106)
-+  FFI_DEFAULT_ABI = FFI_LINUX,
- # else
--#  if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
--  FFI_DEFAULT_ABI = FFI_LINUX,
--#  else
--#   ifdef __NO_FPRS__
--  FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
--#   else
-   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
--#   endif
--#  endif
- # endif
- #endif
- 
- #ifdef POWERPC_AIX
-   FFI_AIX,
-   FFI_DARWIN,
-   FFI_DEFAULT_ABI = FFI_AIX,
- #endif
-@@ -96,32 +101,49 @@ typedef enum ffi_abi {
-   FFI_LAST_ABI
- } ffi_abi;
- #endif
- 
- /* ---- Definitions for closures ----------------------------------------- */
- 
- #define FFI_CLOSURES 1
- #define FFI_NATIVE_RAW_API 0
-+#if defined (POWERPC) || defined (POWERPC_FREEBSD)
-+# define FFI_TARGET_SPECIFIC_VARIADIC 1
-+# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
-+#endif
- 
- /* For additional types like the below, take care about the order in
-    ppc_closures.S. They must follow after the FFI_TYPE_LAST.  */
- 
- /* Needed for soft-float long-double-128 support.  */
- #define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
- 
- /* Needed for FFI_SYSV small structure returns.
-    We use two flag bits, (FLAG_SYSV_SMST_R3, FLAG_SYSV_SMST_R4) which are
-    defined in ffi.c, to determine the exact return type and its size.  */
- #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
- 
--#if defined(POWERPC64) || defined(POWERPC_AIX)
--#define FFI_TRAMPOLINE_SIZE 24
--#else /* POWERPC || POWERPC_AIX */
--#define FFI_TRAMPOLINE_SIZE 40
-+/* Used by ELFv2 for homogenous structure returns.  */
-+#define FFI_V2_TYPE_FLOAT_HOMOG		(FFI_TYPE_LAST + 1)
-+#define FFI_V2_TYPE_DOUBLE_HOMOG	(FFI_TYPE_LAST + 2)
-+#define FFI_V2_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 3)
-+
-+#if _CALL_ELF == 2
-+# define FFI_TRAMPOLINE_SIZE 32
-+#else
-+# if defined(POWERPC64) || defined(POWERPC_AIX)
-+#  if defined(POWERPC_DARWIN64)
-+#    define FFI_TRAMPOLINE_SIZE 48
-+#  else
-+#    define FFI_TRAMPOLINE_SIZE 24
-+#  endif
-+# else /* POWERPC || POWERPC_AIX */
-+#  define FFI_TRAMPOLINE_SIZE 40
-+# endif
- #endif
- 
- #ifndef LIBFFI_ASM
- #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
- struct ffi_aix_trampoline_struct {
-     void * code_pointer;	/* Pointer to ffi_closure_ASM */
-     void * toc;			/* TOC */
-     void * static_chain;	/* Pointer to closure */
-diff --git a/js/src/ctypes/libffi/src/powerpc/linux64.S b/js/src/ctypes/libffi/src/powerpc/linux64.S
---- a/js/src/ctypes/libffi/src/powerpc/linux64.S
-+++ b/js/src/ctypes/libffi/src/powerpc/linux64.S
-@@ -25,56 +25,86 @@
-    DEALINGS IN THE SOFTWARE.
-    ----------------------------------------------------------------------- */
- 
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- 
- #ifdef __powerpc64__
--	.hidden	ffi_call_LINUX64, .ffi_call_LINUX64
--	.globl	ffi_call_LINUX64, .ffi_call_LINUX64
-+	.hidden	ffi_call_LINUX64
-+	.globl	ffi_call_LINUX64
-+# if _CALL_ELF == 2
-+	.text
-+ffi_call_LINUX64:
-+	addis	%r2, %r12, .TOC.-ffi_call_LINUX64@ha
-+	addi	%r2, %r2, .TOC.-ffi_call_LINUX64@l
-+	.localentry ffi_call_LINUX64, . - ffi_call_LINUX64
-+# else
- 	.section	".opd","aw"
- 	.align	3
- ffi_call_LINUX64:
-+#  ifdef _CALL_LINUX
-+	.quad	.L.ffi_call_LINUX64,.TOC.@tocbase,0
-+	.type	ffi_call_LINUX64,@function
-+	.text
-+.L.ffi_call_LINUX64:
-+#  else
-+	.hidden	.ffi_call_LINUX64
-+	.globl	.ffi_call_LINUX64
- 	.quad	.ffi_call_LINUX64,.TOC.@tocbase,0
- 	.size	ffi_call_LINUX64,24
- 	.type	.ffi_call_LINUX64,@function
- 	.text
- .ffi_call_LINUX64:
-+#  endif
-+# endif
- .LFB1:
- 	mflr	%r0
- 	std	%r28, -32(%r1)
- 	std	%r29, -24(%r1)
- 	std	%r30, -16(%r1)
- 	std	%r31, -8(%r1)
- 	std	%r0, 16(%r1)
- 
- 	mr	%r28, %r1	/* our AP.  */
- .LCFI0:
- 	stdux	%r1, %r1, %r4
- 	mr	%r31, %r5	/* flags, */
- 	mr	%r30, %r6	/* rvalue, */
- 	mr	%r29, %r7	/* function address.  */
-+/* Save toc pointer, not for the ffi_prep_args64 call, but for the later
-+   bctrl function call.  */
-+# if _CALL_ELF == 2
-+	std	%r2, 24(%r1)
-+# else
- 	std	%r2, 40(%r1)
-+# endif
- 
- 	/* Call ffi_prep_args64.  */
- 	mr	%r4, %r1
-+# if defined _CALL_LINUX || _CALL_ELF == 2
-+	bl	ffi_prep_args64
-+# else
- 	bl	.ffi_prep_args64
-+# endif
- 
--	ld	%r0, 0(%r29)
-+# if _CALL_ELF == 2
-+	mr	%r12, %r29
-+# else
-+	ld	%r12, 0(%r29)
- 	ld	%r2, 8(%r29)
- 	ld	%r11, 16(%r29)
--
-+# endif
- 	/* Now do the call.  */
- 	/* Set up cr1 with bits 4-7 of the flags.  */
- 	mtcrf	0x40, %r31
- 
- 	/* Get the address to call into CTR.  */
--	mtctr	%r0
-+	mtctr	%r12
- 	/* Load all those argument registers.  */
- 	ld	%r3, -32-(8*8)(%r28)
- 	ld	%r4, -32-(7*8)(%r28)
- 	ld	%r5, -32-(6*8)(%r28)
- 	ld	%r6, -32-(5*8)(%r28)
- 	bf-	5, 1f
- 	ld	%r7, -32-(4*8)(%r28)
- 	ld	%r8, -32-(3*8)(%r28)
-@@ -99,50 +129,93 @@ 1:
- 	lfd	%f13, -32-(9*8)(%r28)
- 2:
- 
- 	/* Make the call.  */
- 	bctrl
- 
- 	/* This must follow the call immediately, the unwinder
- 	   uses this to find out if r2 has been saved or not.  */
-+# if _CALL_ELF == 2
-+	ld	%r2, 24(%r1)
-+# else
- 	ld	%r2, 40(%r1)
-+# endif
- 
- 	/* Now, deal with the return value.  */
- 	mtcrf	0x01, %r31
--	bt-	30, .Ldone_return_value
--	bt-	29, .Lfp_return_value
-+	bt	31, .Lstruct_return_value
-+	bt	30, .Ldone_return_value
-+	bt	29, .Lfp_return_value
- 	std	%r3, 0(%r30)
- 	/* Fall through...  */
- 
- .Ldone_return_value:
- 	/* Restore the registers we used and return.  */
- 	mr	%r1, %r28
- 	ld	%r0, 16(%r28)
--	ld	%r28, -32(%r1)
-+	ld	%r28, -32(%r28)
- 	mtlr	%r0
- 	ld	%r29, -24(%r1)
- 	ld	%r30, -16(%r1)
- 	ld	%r31, -8(%r1)
- 	blr
- 
- .Lfp_return_value:
- 	bf	28, .Lfloat_return_value
- 	stfd	%f1, 0(%r30)
- 	mtcrf	0x02, %r31 /* cr6  */
- 	bf	27, .Ldone_return_value
- 	stfd	%f2, 8(%r30)
- 	b	.Ldone_return_value
- .Lfloat_return_value:
- 	stfs	%f1, 0(%r30)
- 	b	.Ldone_return_value
-+
-+.Lstruct_return_value:
-+	bf	29, .Lsmall_struct
-+	bf	28, .Lfloat_homog_return_value
-+	stfd	%f1, 0(%r30)
-+	stfd	%f2, 8(%r30)
-+	stfd	%f3, 16(%r30)
-+	stfd	%f4, 24(%r30)
-+	stfd	%f5, 32(%r30)
-+	stfd	%f6, 40(%r30)
-+	stfd	%f7, 48(%r30)
-+	stfd	%f8, 56(%r30)
-+	b	.Ldone_return_value
-+
-+.Lfloat_homog_return_value:
-+	stfs	%f1, 0(%r30)
-+	stfs	%f2, 4(%r30)
-+	stfs	%f3, 8(%r30)
-+	stfs	%f4, 12(%r30)
-+	stfs	%f5, 16(%r30)
-+	stfs	%f6, 20(%r30)
-+	stfs	%f7, 24(%r30)
-+	stfs	%f8, 28(%r30)
-+	b	.Ldone_return_value
-+
-+.Lsmall_struct:
-+	std	%r3, 0(%r30)
-+	std	%r4, 8(%r30)
-+	b	.Ldone_return_value
-+
- .LFE1:
- 	.long	0
- 	.byte	0,12,0,1,128,4,0,0
-+# if _CALL_ELF == 2
-+	.size	ffi_call_LINUX64,.-ffi_call_LINUX64
-+# else
-+#  ifdef _CALL_LINUX
-+	.size	ffi_call_LINUX64,.-.L.ffi_call_LINUX64
-+#  else
- 	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64
-+#  endif
-+# endif
- 
- 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
- .Lframe1:
- 	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
- .LSCIE1:
- 	.4byte	0x0	 # CIE Identifier Tag
- 	.byte	0x1	 # CIE Version
- 	.ascii "zR\0"	 # CIE Augmentation
-@@ -175,13 +248,13 @@ 2:
- 	.byte	0x9e	 # DW_CFA_offset, column 0x1e
- 	.uleb128 0x2
- 	.byte	0x9d	 # DW_CFA_offset, column 0x1d
- 	.uleb128 0x3
- 	.byte	0x9c	 # DW_CFA_offset, column 0x1c
- 	.uleb128 0x4
- 	.align 3
- .LEFDE1:
-+
-+# if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
-+	.section	.note.GNU-stack,"",@progbits
-+# endif
- #endif
--
--#if defined __ELF__ && defined __linux__
--	.section	.note.GNU-stack,"",@progbits
--#endif
-diff --git a/js/src/ctypes/libffi/src/powerpc/linux64_closure.S b/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
---- a/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
-+++ b/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
-@@ -27,179 +27,332 @@
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- 
- 	.file	"linux64_closure.S"
- 
- #ifdef __powerpc64__
- 	FFI_HIDDEN (ffi_closure_LINUX64)
--	FFI_HIDDEN (.ffi_closure_LINUX64)
--	.globl  ffi_closure_LINUX64, .ffi_closure_LINUX64
-+	.globl  ffi_closure_LINUX64
-+# if _CALL_ELF == 2
-+	.text
-+ffi_closure_LINUX64:
-+	addis	%r2, %r12, .TOC.-ffi_closure_LINUX64@ha
-+	addi	%r2, %r2, .TOC.-ffi_closure_LINUX64@l
-+	.localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64
-+# else
- 	.section        ".opd","aw"
- 	.align  3
- ffi_closure_LINUX64:
-+#  ifdef _CALL_LINUX
-+	.quad   .L.ffi_closure_LINUX64,.TOC.@tocbase,0
-+	.type   ffi_closure_LINUX64,@function
-+	.text
-+.L.ffi_closure_LINUX64:
-+#  else
-+	FFI_HIDDEN (.ffi_closure_LINUX64)
-+	.globl  .ffi_closure_LINUX64
- 	.quad   .ffi_closure_LINUX64,.TOC.@tocbase,0
- 	.size   ffi_closure_LINUX64,24
- 	.type   .ffi_closure_LINUX64,@function
- 	.text
- .ffi_closure_LINUX64:
-+#  endif
-+# endif
-+
-+# if _CALL_ELF == 2
-+#  32 byte special reg save area + 64 byte parm save area and retval
-+#  + 13*8 fpr save area + round to 16
-+#  define STACKFRAME 208
-+#  define PARMSAVE 32
-+#  No parameter save area is needed for the call to ffi_closure_helper_LINUX64,
-+#  so return value can start there.
-+#  define RETVAL PARMSAVE
-+# else
-+#  48 bytes special reg save area + 64 bytes parm save area
-+#  + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
-+#  define STACKFRAME 240
-+#  define PARMSAVE 48
-+#  define RETVAL PARMSAVE+64
-+# endif
-+
- .LFB1:
--	# save general regs into parm save area
--	std	%r3, 48(%r1)
--	std	%r4, 56(%r1)
--	std	%r5, 64(%r1)
--	std	%r6, 72(%r1)
-+# if _CALL_ELF == 2
-+	ld	%r12, FFI_TRAMPOLINE_SIZE(%r11)		# closure->cif
- 	mflr	%r0
-+	lwz	%r12, 28(%r12)				# cif->flags
-+	mtcrf	0x40, %r12
-+	addi	%r12, %r1, PARMSAVE
-+	bt	7, .Lparmsave
-+	# Our caller has not allocated a parameter save area.
-+	# We need to allocate one here and use it to pass gprs to
-+	# ffi_closure_helper_LINUX64.  The return value area will do.
-+	addi	%r12, %r1, -STACKFRAME+RETVAL
-+.Lparmsave:
-+	std	%r0, 16(%r1)
-+	# Save general regs into parm save area
-+	std	%r3, 0(%r12)
-+	std	%r4, 8(%r12)
-+	std	%r5, 16(%r12)
-+	std	%r6, 24(%r12)
-+	std	%r7, 32(%r12)
-+	std	%r8, 40(%r12)
-+	std	%r9, 48(%r12)
-+	std	%r10, 56(%r12)
- 
--	std	%r7, 80(%r1)
--	std	%r8, 88(%r1)
--	std	%r9, 96(%r1)
--	std	%r10, 104(%r1)
-+	# load up the pointer to the parm save area
-+	mr	%r5, %r12
-+# else
-+	mflr	%r0
-+	# Save general regs into parm save area
-+	# This is the parameter save area set up by our caller.
-+	std	%r3, PARMSAVE+0(%r1)
-+	std	%r4, PARMSAVE+8(%r1)
-+	std	%r5, PARMSAVE+16(%r1)
-+	std	%r6, PARMSAVE+24(%r1)
-+	std	%r7, PARMSAVE+32(%r1)
-+	std	%r8, PARMSAVE+40(%r1)
-+	std	%r9, PARMSAVE+48(%r1)
-+	std	%r10, PARMSAVE+56(%r1)
-+
- 	std	%r0, 16(%r1)
- 
--	# mandatory 48 bytes special reg save area + 64 bytes parm save area
--	# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
--	stdu	%r1, -240(%r1)
-+	# load up the pointer to the parm save area
-+	addi	%r5, %r1, PARMSAVE
-+# endif
-+
-+	# next save fpr 1 to fpr 13
-+	stfd	%f1, -104+(0*8)(%r1)
-+	stfd	%f2, -104+(1*8)(%r1)
-+	stfd	%f3, -104+(2*8)(%r1)
-+	stfd	%f4, -104+(3*8)(%r1)
-+	stfd	%f5, -104+(4*8)(%r1)
-+	stfd	%f6, -104+(5*8)(%r1)
-+	stfd	%f7, -104+(6*8)(%r1)
-+	stfd	%f8, -104+(7*8)(%r1)
-+	stfd	%f9, -104+(8*8)(%r1)
-+	stfd	%f10, -104+(9*8)(%r1)
-+	stfd	%f11, -104+(10*8)(%r1)
-+	stfd	%f12, -104+(11*8)(%r1)
-+	stfd	%f13, -104+(12*8)(%r1)
-+
-+	# load up the pointer to the saved fpr registers */
-+	addi	%r6, %r1, -104
-+
-+	# load up the pointer to the result storage
-+	addi	%r4, %r1, -STACKFRAME+RETVAL
-+
-+	stdu	%r1, -STACKFRAME(%r1)
- .LCFI0:
- 
--	# next save fpr 1 to fpr 13
--	stfd  %f1, 128+(0*8)(%r1)
--	stfd  %f2, 128+(1*8)(%r1)
--	stfd  %f3, 128+(2*8)(%r1)
--	stfd  %f4, 128+(3*8)(%r1)
--	stfd  %f5, 128+(4*8)(%r1)
--	stfd  %f6, 128+(5*8)(%r1)
--	stfd  %f7, 128+(6*8)(%r1)
--	stfd  %f8, 128+(7*8)(%r1)
--	stfd  %f9, 128+(8*8)(%r1)
--	stfd  %f10, 128+(9*8)(%r1)
--	stfd  %f11, 128+(10*8)(%r1)
--	stfd  %f12, 128+(11*8)(%r1)
--	stfd  %f13, 128+(12*8)(%r1)
--
--	# set up registers for the routine that actually does the work
- 	# get the context pointer from the trampoline
--	mr %r3, %r11
--
--	# now load up the pointer to the result storage
--	addi %r4, %r1, 112
--
--	# now load up the pointer to the parameter save area
--	# in the previous frame
--	addi %r5, %r1, 240 + 48
--
--	# now load up the pointer to the saved fpr registers */
--	addi %r6, %r1, 128
-+	mr	%r3, %r11
- 
- 	# make the call
-+# if defined _CALL_LINUX || _CALL_ELF == 2
-+	bl ffi_closure_helper_LINUX64
-+# else
- 	bl .ffi_closure_helper_LINUX64
-+# endif
- .Lret:
- 
- 	# now r3 contains the return type
- 	# so use it to look up in a table
- 	# so we know how to deal with each type
- 
- 	# look up the proper starting point in table
- 	# by using return type as offset
-+	ld %r0, STACKFRAME+16(%r1)
-+	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT
-+	bge .Lsmall
- 	mflr %r4		# move address of .Lret to r4
- 	sldi %r3, %r3, 4	# now multiply return type by 16
- 	addi %r4, %r4, .Lret_type0 - .Lret
--	ld %r0, 240+16(%r1)
- 	add %r3, %r3, %r4	# add contents of table to table address
- 	mtctr %r3
- 	bctr			# jump to it
- 
- # Each of the ret_typeX code fragments has to be exactly 16 bytes long
- # (4 instructions). For cache effectiveness we align to a 16 byte boundary
- # first.
- 	.align 4
- 
- .Lret_type0:
- # case FFI_TYPE_VOID
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- 	nop
- # case FFI_TYPE_INT
--	lwa %r3, 112+4(%r1)
-+# ifdef __LITTLE_ENDIAN__
-+	lwa %r3, RETVAL+0(%r1)
-+# else
-+	lwa %r3, RETVAL+4(%r1)
-+# endif
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_FLOAT
--	lfs %f1, 112+0(%r1)
-+	lfs %f1, RETVAL+0(%r1)
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_DOUBLE
--	lfd %f1, 112+0(%r1)
-+	lfd %f1, RETVAL+0(%r1)
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_LONGDOUBLE
--	lfd %f1, 112+0(%r1)
-+	lfd %f1, RETVAL+0(%r1)
- 	mtlr %r0
--	lfd %f2, 112+8(%r1)
-+	lfd %f2, RETVAL+8(%r1)
- 	b .Lfinish
- # case FFI_TYPE_UINT8
--	lbz %r3, 112+7(%r1)
-+# ifdef __LITTLE_ENDIAN__
-+	lbz %r3, RETVAL+0(%r1)
-+# else
-+	lbz %r3, RETVAL+7(%r1)
-+# endif
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_SINT8
--	lbz %r3, 112+7(%r1)
-+# ifdef __LITTLE_ENDIAN__
-+	lbz %r3, RETVAL+0(%r1)
-+# else
-+	lbz %r3, RETVAL+7(%r1)
-+# endif
- 	extsb %r3,%r3
- 	mtlr %r0
- 	b .Lfinish
- # case FFI_TYPE_UINT16
--	lhz %r3, 112+6(%r1)
-+# ifdef __LITTLE_ENDIAN__
-+	lhz %r3, RETVAL+0(%r1)
-+# else
-+	lhz %r3, RETVAL+6(%r1)
-+# endif
- 	mtlr %r0
- .Lfinish:
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_SINT16
--	lha %r3, 112+6(%r1)
-+# ifdef __LITTLE_ENDIAN__
-+	lha %r3, RETVAL+0(%r1)
-+# else
-+	lha %r3, RETVAL+6(%r1)
-+# endif
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_UINT32
--	lwz %r3, 112+4(%r1)
-+# ifdef __LITTLE_ENDIAN__
-+	lwz %r3, RETVAL+0(%r1)
-+# else
-+	lwz %r3, RETVAL+4(%r1)
-+# endif
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_SINT32
--	lwa %r3, 112+4(%r1)
-+# ifdef __LITTLE_ENDIAN__
-+	lwa %r3, RETVAL+0(%r1)
-+# else
-+	lwa %r3, RETVAL+4(%r1)
-+# endif
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_UINT64
--	ld %r3, 112+0(%r1)
-+	ld %r3, RETVAL+0(%r1)
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_SINT64
--	ld %r3, 112+0(%r1)
-+	ld %r3, RETVAL+0(%r1)
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- # case FFI_TYPE_STRUCT
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
- 	nop
- # case FFI_TYPE_POINTER
--	ld %r3, 112+0(%r1)
-+	ld %r3, RETVAL+0(%r1)
- 	mtlr %r0
--	addi %r1, %r1, 240
-+	addi %r1, %r1, STACKFRAME
- 	blr
--# esac
-+# case FFI_V2_TYPE_FLOAT_HOMOG
-+	lfs %f1, RETVAL+0(%r1)
-+	lfs %f2, RETVAL+4(%r1)
-+	lfs %f3, RETVAL+8(%r1)
-+	b .Lmorefloat
-+# case FFI_V2_TYPE_DOUBLE_HOMOG
-+	lfd %f1, RETVAL+0(%r1)
-+	lfd %f2, RETVAL+8(%r1)
-+	lfd %f3, RETVAL+16(%r1)
-+	lfd %f4, RETVAL+24(%r1)
-+	mtlr %r0
-+	lfd %f5, RETVAL+32(%r1)
-+	lfd %f6, RETVAL+40(%r1)
-+	lfd %f7, RETVAL+48(%r1)
-+	lfd %f8, RETVAL+56(%r1)
-+	addi %r1, %r1, STACKFRAME
-+	blr
-+.Lmorefloat:
-+	lfs %f4, RETVAL+12(%r1)
-+	mtlr %r0
-+	lfs %f5, RETVAL+16(%r1)
-+	lfs %f6, RETVAL+20(%r1)
-+	lfs %f7, RETVAL+24(%r1)
-+	lfs %f8, RETVAL+28(%r1)
-+	addi %r1, %r1, STACKFRAME
-+	blr
-+.Lsmall:
-+# ifdef __LITTLE_ENDIAN__
-+	ld %r3,RETVAL+0(%r1)
-+	mtlr %r0
-+	ld %r4,RETVAL+8(%r1)
-+	addi %r1, %r1, STACKFRAME
-+	blr
-+# else
-+	# A struct smaller than a dword is returned in the low bits of r3
-+	# ie. right justified.  Larger structs are passed left justified
-+	# in r3 and r4.  The return value area on the stack will have
-+	# the structs as they are usually stored in memory.
-+	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes?
-+	neg %r5, %r3
-+	ld %r3,RETVAL+0(%r1)
-+	blt .Lsmalldown
-+	mtlr %r0
-+	ld %r4,RETVAL+8(%r1)
-+	addi %r1, %r1, STACKFRAME
-+	blr
-+.Lsmalldown:
-+	addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
-+	mtlr %r0
-+	sldi %r5, %r5, 3
-+	addi %r1, %r1, STACKFRAME
-+	srd %r3, %r3, %r5
-+	blr
-+# endif
-+
- .LFE1:
- 	.long	0
- 	.byte	0,12,0,1,128,0,0,0
-+# if _CALL_ELF == 2
-+	.size	ffi_closure_LINUX64,.-ffi_closure_LINUX64
-+# else
-+#  ifdef _CALL_LINUX
-+	.size	ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
-+#  else
- 	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
-+#  endif
-+# endif
- 
- 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
- .Lframe1:
- 	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
- .LSCIE1:
- 	.4byte	0x0	 # CIE Identifier Tag
- 	.byte	0x1	 # CIE Version
- 	.ascii "zR\0"	 # CIE Augmentation
-@@ -218,19 +371,19 @@ ffi_closure_LINUX64:
- .LASFDE1:
- 	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
- 	.8byte	.LFB1-.	 # FDE initial location
- 	.8byte	.LFE1-.LFB1	 # FDE address range
- 	.uleb128 0x0	 # Augmentation size
- 	.byte	0x2	 # DW_CFA_advance_loc1
- 	.byte	.LCFI0-.LFB1
- 	.byte	0xe	 # DW_CFA_def_cfa_offset
--	.uleb128 240
-+	.uleb128 STACKFRAME
- 	.byte	0x11	 # DW_CFA_offset_extended_sf
- 	.uleb128 0x41
- 	.sleb128 -2
- 	.align 3
- .LEFDE1:
-+
-+# if defined __ELF__ && defined __linux__
-+	.section	.note.GNU-stack,"",@progbits
-+# endif
- #endif
--
--#if defined __ELF__ && defined __linux__
--	.section	.note.GNU-stack,"",@progbits
--#endif
-diff --git a/js/src/ctypes/libffi/src/powerpc/ppc_closure.S b/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
---- a/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
-+++ b/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
-@@ -117,53 +117,88 @@ ENTRY(ffi_closure_SYSV)
- # case FFI_TYPE_INT
- 	lwz %r3,112+0(%r1)
- 	mtlr %r0
- .Lfinish:
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_TYPE_FLOAT
-+#ifndef __NO_FPRS__
- 	lfs %f1,112+0(%r1)
- 	mtlr %r0
- 	addi %r1,%r1,144
-+#else
-+	nop
-+	nop
-+	nop
-+#endif
- 	blr
- 
- # case FFI_TYPE_DOUBLE
-+#ifndef __NO_FPRS__
- 	lfd %f1,112+0(%r1)
- 	mtlr %r0
- 	addi %r1,%r1,144
-+#else
-+	nop
-+	nop
-+	nop
-+#endif
- 	blr
- 
- # case FFI_TYPE_LONGDOUBLE
-+#ifndef __NO_FPRS__
- 	lfd %f1,112+0(%r1)
- 	lfd %f2,112+8(%r1)
- 	mtlr %r0
- 	b .Lfinish
-+#else
-+	nop
-+	nop
-+	nop
-+	blr
-+#endif
- 
- # case FFI_TYPE_UINT8
-+#ifdef __LITTLE_ENDIAN__
-+	lbz %r3,112+0(%r1)
-+#else
- 	lbz %r3,112+3(%r1)
-+#endif
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_TYPE_SINT8
-+#ifdef __LITTLE_ENDIAN__
-+	lbz %r3,112+0(%r1)
-+#else
- 	lbz %r3,112+3(%r1)
-+#endif
- 	extsb %r3,%r3
- 	mtlr %r0
- 	b .Lfinish
- 
- # case FFI_TYPE_UINT16
-+#ifdef __LITTLE_ENDIAN__
-+	lhz %r3,112+0(%r1)
-+#else
- 	lhz %r3,112+2(%r1)
-+#endif
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_TYPE_SINT16
-+#ifdef __LITTLE_ENDIAN__
-+	lha %r3,112+0(%r1)
-+#else
- 	lha %r3,112+2(%r1)
-+#endif
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_TYPE_UINT32
- 	lwz %r3,112+0(%r1)
- 	mtlr %r0
- 	addi %r1,%r1,144
-@@ -198,76 +233,99 @@ ENTRY(ffi_closure_SYSV)
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_TYPE_UINT128
- 	lwz %r3,112+0(%r1)
- 	lwz %r4,112+4(%r1)
- 	lwz %r5,112+8(%r1)
--	bl .Luint128
-+	b .Luint128
- 
- # The return types below are only used when the ABI type is FFI_SYSV.
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
- 	lbz %r3,112+0(%r1)
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
- 	lhz %r3,112+0(%r1)
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
- 	lwz %r3,112+0(%r1)
-+#ifdef __LITTLE_ENDIAN__
-+	mtlr %r0
-+	addi %r1,%r1,144
-+	blr
-+#else
- 	srwi %r3,%r3,8
- 	mtlr %r0
- 	b .Lfinish
-+#endif
- 
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
- 	lwz %r3,112+0(%r1)
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
- 	lwz %r3,112+0(%r1)
- 	lwz %r4,112+4(%r1)
-+#ifdef __LITTLE_ENDIAN__
-+	mtlr %r0
-+	b .Lfinish
-+#else
- 	li %r5,24
- 	b .Lstruct567
-+#endif
- 
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
- 	lwz %r3,112+0(%r1)
- 	lwz %r4,112+4(%r1)
-+#ifdef __LITTLE_ENDIAN__
-+	mtlr %r0
-+	b .Lfinish
-+#else
- 	li %r5,16
- 	b .Lstruct567
-+#endif
- 
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
- 	lwz %r3,112+0(%r1)
- 	lwz %r4,112+4(%r1)
-+#ifdef __LITTLE_ENDIAN__
-+	mtlr %r0
-+	b .Lfinish
-+#else
- 	li %r5,8
- 	b .Lstruct567
-+#endif
- 
- # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
- 	lwz %r3,112+0(%r1)
- 	lwz %r4,112+4(%r1)
- 	mtlr %r0
- 	b .Lfinish
- 
-+#ifndef __LITTLE_ENDIAN__
- .Lstruct567:
- 	subfic %r6,%r5,32
- 	srw %r4,%r4,%r5
- 	slw %r6,%r3,%r6
- 	srw %r3,%r3,%r5
- 	or %r4,%r6,%r4
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
-+#endif
- 
- .Luint128:
- 	lwz %r6,112+12(%r1)
- 	mtlr %r0
- 	addi %r1,%r1,144
- 	blr
- 
- END(ffi_closure_SYSV)
-diff --git a/js/src/ctypes/libffi/src/powerpc/sysv.S b/js/src/ctypes/libffi/src/powerpc/sysv.S
---- a/js/src/ctypes/libffi/src/powerpc/sysv.S
-+++ b/js/src/ctypes/libffi/src/powerpc/sysv.S
-@@ -78,37 +78,41 @@ ENTRY(ffi_call_SYSV)
- 	nop
- 	lwz	%r7,-16-(4*4)(%r28)
- 	lwz	%r8,-16-(3*4)(%r28)
- 	lwz	%r9,-16-(2*4)(%r28)
- 	lwz	%r10,-16-(1*4)(%r28)
- 	nop
- 1:
- 
-+#ifndef __NO_FPRS__
- 	/* Load all the FP registers.  */
- 	bf-	6,2f
- 	lfd	%f1,-16-(8*4)-(8*8)(%r28)
- 	lfd	%f2,-16-(8*4)-(7*8)(%r28)
- 	lfd	%f3,-16-(8*4)-(6*8)(%r28)
- 	lfd	%f4,-16-(8*4)-(5*8)(%r28)
- 	nop
- 	lfd	%f5,-16-(8*4)-(4*8)(%r28)
- 	lfd	%f6,-16-(8*4)-(3*8)(%r28)
- 	lfd	%f7,-16-(8*4)-(2*8)(%r28)
- 	lfd	%f8,-16-(8*4)-(1*8)(%r28)
-+#endif
- 2:
- 
- 	/* Make the call.  */
- 	bctrl
- 
- 	/* Now, deal with the return value.  */
- 	mtcrf	0x01,%r31 /* cr7  */
- 	bt-	31,L(small_struct_return_value)
- 	bt-	30,L(done_return_value)
-+#ifndef __NO_FPRS__
- 	bt-	29,L(fp_return_value)
-+#endif
- 	stw	%r3,0(%r30)
- 	bf+	28,L(done_return_value)
- 	stw	%r4,4(%r30)
- 	mtcrf	0x02,%r31 /* cr6  */
- 	bf	27,L(done_return_value)
- 	stw     %r5,8(%r30)
- 	stw	%r6,12(%r30)
- 	/* Fall through...  */
-@@ -119,41 +123,38 @@ L(done_return_value):
- 	lwz	%r31, -4(%r28)
- 	mtlr	%r9
- 	lwz	%r30, -8(%r28)
- 	lwz	%r29,-12(%r28)
- 	lwz	%r28,-16(%r28)
- 	lwz	%r1,0(%r1)
- 	blr
- 
-+#ifndef __NO_FPRS__
- L(fp_return_value):
- 	bf	28,L(float_return_value)
- 	stfd	%f1,0(%r30)
- 	mtcrf   0x02,%r31 /* cr6  */
- 	bf	27,L(done_return_value)
- 	stfd	%f2,8(%r30)
- 	b	L(done_return_value)
- L(float_return_value):
- 	stfs	%f1,0(%r30)
- 	b	L(done_return_value)
-+#endif
- 
- L(small_struct_return_value):
--	extrwi	%r6,%r31,2,19         /* number of bytes padding = shift/8 */
--	mtcrf	0x02,%r31	      /* copy flags to cr[24:27] (cr6) */
--	extrwi	%r5,%r31,5,19         /* r5 <- number of bits of padding */
--	subfic  %r6,%r6,4             /* r6 <- number of useful bytes in r3 */
--	bf-	25,L(done_return_value) /* struct in r3 ? if not, done. */
--/* smst_one_register: */
--	slw	%r3,%r3,%r5           /* Left-justify value in r3 */
--	mtxer	%r6                   /* move byte count to XER ... */
--	stswx	%r3,0,%r30            /* ... and store that many bytes */
--	bf+	26,L(done_return_value)  /* struct in r3:r4 ? */
--	add	%r6,%r6,%r30          /* adjust pointer */
--	stswi	%r4,%r6,4             /* store last four bytes */
--	b	L(done_return_value)
-+	/*
-+	 * The C code always allocates a properly-aligned 8-byte bounce
-+	 * buffer to make this assembly code very simple.  Just write out
-+	 * r3 and r4 to the buffer to allow the C code to handle the rest.
-+	 */
-+	stw %r3, 0(%r30)
-+	stw %r4, 4(%r30)
-+	b L(done_return_value)
- 
- .LFE1:
- END(ffi_call_SYSV)
- 
-       .section	".eh_frame",EH_FRAME_FLAGS,@progbits
- .Lframe1:
-       .4byte    .LECIE1-.LSCIE1  /*  Length of Common Information Entry */
- .LSCIE1:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-ppc64le-build.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,4491 @@
+# HG changeset patch
+# Parent 007cf000fdf7c5048939a87f63165a67fd9db5f6
+# User Ulrich Weigand <uweigand@de.ibm.com>
+Bug 976648 - powerpc64le-linux support - toplevel build/config
+
+diff --git a/build/autoconf/config.guess b/build/autoconf/config.guess
+--- a/build/autoconf/config.guess
++++ b/build/autoconf/config.guess
+@@ -1,47 +1,41 @@
+ #! /bin/sh
+ # Attempt to guess a canonical system name.
+-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-#   Free Software Foundation, Inc.
++#   Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+-timestamp='2009-08-19'
++timestamp='2014-02-12'
+ 
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ # General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
+-
+-
+-# Originally written by Per Bothner.  Please send patches (context
+-# diff format) to <config-patches@gnu.org> and include a ChangeLog
+-# entry.
++# the same distribution terms that you use for the rest of that
++# program.  This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ #
+-# This script attempts to guess a canonical system name similar to
+-# config.sub.  If it succeeds, it prints the system name on stdout, and
+-# exits with 0.  Otherwise, it exits with 1.
++# Originally written by Per Bothner.
+ #
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++#
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++
+ 
+ me=`echo "$0" | sed -e 's,.*/,,'`
+ 
+ usage="\
+ Usage: $0 [OPTION]
+ 
+ Output the configuration name of the system \`$me' is run on.
+ 
+@@ -51,18 +45,17 @@ Operation modes:
+   -v, --version      print version number, then exit
+ 
+ Report bugs and patches to <config-patches@gnu.org>."
+ 
+ version="\
+ GNU config.guess ($timestamp)
+ 
+ Originally written by Per Bothner.
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+ This is free software; see the source for copying conditions.  There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+ 
+ help="
+ Try \`$me --help' for more information."
+ 
+ # Parse command line
+@@ -134,22 +127,43 @@ if (test -f /.attbin/uname) >/dev/null 2
+ 	PATH=$PATH:/.attbin ; export PATH
+ fi
+ 
+ UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+ UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+ 
++case "${UNAME_SYSTEM}" in
++Linux|GNU|GNU/*)
++	# If the system lacks a compiler, then just pick glibc.
++	# We could probably try harder.
++	LIBC=gnu
++
++	eval $set_cc_for_build
++	cat <<-EOF > $dummy.c
++	#include <features.h>
++	#if defined(__UCLIBC__)
++	LIBC=uclibc
++	#elif defined(__dietlibc__)
++	LIBC=dietlibc
++	#else
++	LIBC=gnu
++	#endif
++	EOF
++	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
++	;;
++esac
++
+ # Note: order is significant - the case branches are not exclusive.
+ 
+ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+     *:NetBSD:*:*)
+ 	# NetBSD (nbsd) targets should (where applicable) match one or
+-	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
++	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ 	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+ 	# switched to ELF, *-*-netbsd* would select the old
+ 	# object file format.  This provides both forward
+ 	# compatibility and a consistent mechanism for selecting the
+ 	# object file format.
+ 	#
+ 	# Note: NetBSD doesn't particularly care about the vendor
+ 	# portion of the name.  We always set it to "unknown".
+@@ -175,17 +189,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ 		    # Return netbsd for either.  FIX?
+ 		    os=netbsd
+ 		else
+ 		    os=netbsdelf
+ 		fi
+ 		;;
+ 	    *)
+-	        os=netbsd
++		os=netbsd
+ 		;;
+ 	esac
+ 	# The OS release
+ 	# Debian GNU/NetBSD machines have a different userland, and
+ 	# thus, need a distinct triplet. However, they do not need
+ 	# kernel version information, so it can be replaced with a
+ 	# suitable tag, in the style of linux-gnu.
+ 	case "${UNAME_VERSION}" in
+@@ -196,16 +210,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ 		;;
+ 	esac
+ 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ 	# contains redundant information, the shorter form:
+ 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ 	echo "${machine}-${os}${release}"
+ 	exit ;;
++    *:Bitrig:*:*)
++	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
++	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
++	exit ;;
+     *:OpenBSD:*:*)
+ 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ 	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ 	exit ;;
+     *:ekkoBSD:*:*)
+ 	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ 	exit ;;
+     *:SolidBSD:*:*)
+@@ -218,17 +236,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ 	exit ;;
+     alpha:OSF1:*:*)
+ 	case $UNAME_RELEASE in
+ 	*4.0)
+ 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ 		;;
+ 	*5.*)
+-	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
++		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ 		;;
+ 	esac
+ 	# According to Compaq, /usr/sbin/psrinfo has been available on
+ 	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+ 	# covers most systems running today.  This code pipes the CPU
+ 	# types through head -n 1, so we only detect the type of CPU 0.
+ 	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ 	case "$ALPHA_CPU_TYPE" in
+@@ -264,17 +282,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 		UNAME_MACHINE="alphaev79" ;;
+ 	esac
+ 	# A Pn.n version is a patched version.
+ 	# A Vn.n version is a released version.
+ 	# A Tn.n version is a released field test version.
+ 	# A Xn.n version is an unreleased experimental baselevel.
+ 	# 1.2 uses "1.2" for uname -r.
+ 	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+-	exit ;;
++	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
++	exitcode=$?
++	trap '' 0
++	exit $exitcode ;;
+     Alpha\ *:Windows_NT*:*)
+ 	# How do we know it's Interix rather than the generic POSIX subsystem?
+ 	# Should we change UNAME_MACHINE based on the output of uname instead
+ 	# of the specific Alpha model?
+ 	echo alpha-pc-interix
+ 	exit ;;
+     21064:Windows_NT:50:3)
+ 	echo alpha-dec-winnt3.5
+@@ -290,22 +311,22 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 	exit ;;
+     *:OS/390:*:*)
+ 	echo i370-ibm-openedition
+ 	exit ;;
+     *:z/VM:*:*)
+ 	echo s390-ibm-zvmoe
+ 	exit ;;
+     *:OS400:*:*)
+-        echo powerpc-ibm-os400
++	echo powerpc-ibm-os400
+ 	exit ;;
+     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ 	echo arm-acorn-riscix${UNAME_RELEASE}
+ 	exit ;;
+-    arm:riscos:*:*|arm:RISCOS:*:*)
++    arm*:riscos:*:*|arm*:RISCOS:*:*)
+ 	echo arm-unknown-riscos
+ 	exit ;;
+     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ 	echo hppa1.1-hitachi-hiuxmpp
+ 	exit ;;
+     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ 	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ 	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+@@ -328,16 +349,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
+     sun4H:SunOS:5.*:*)
+ 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
+     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ 	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
++    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
++	echo i386-pc-auroraux${UNAME_RELEASE}
++	exit ;;
+     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ 	eval $set_cc_for_build
+ 	SUN_ARCH="i386"
+ 	# If there is a compiler, see if it is configured for 64-bit objects.
+ 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ 	# This test works for both compilers.
+ 	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+@@ -386,33 +410,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+     # can be virtually everything (everything which is not
+     # "atarist" or "atariste" at least should have a processor
+     # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+     # to the lowercase version "mint" (or "freemint").  Finally
+     # the system name "TOS" denotes a system which is actually not
+     # MiNT.  But MiNT is downward compatible to TOS, so this should
+     # be no problem.
+     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+-        echo m68k-atari-mint${UNAME_RELEASE}
++	echo m68k-atari-mint${UNAME_RELEASE}
+ 	exit ;;
+     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ 	echo m68k-atari-mint${UNAME_RELEASE}
+-        exit ;;
++	exit ;;
+     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+-        echo m68k-atari-mint${UNAME_RELEASE}
++	echo m68k-atari-mint${UNAME_RELEASE}
+ 	exit ;;
+     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+-        echo m68k-milan-mint${UNAME_RELEASE}
+-        exit ;;
++	echo m68k-milan-mint${UNAME_RELEASE}
++	exit ;;
+     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+-        echo m68k-hades-mint${UNAME_RELEASE}
+-        exit ;;
++	echo m68k-hades-mint${UNAME_RELEASE}
++	exit ;;
+     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+-        echo m68k-unknown-mint${UNAME_RELEASE}
+-        exit ;;
++	echo m68k-unknown-mint${UNAME_RELEASE}
++	exit ;;
+     m68k:machten:*:*)
+ 	echo m68k-apple-machten${UNAME_RELEASE}
+ 	exit ;;
+     powerpc:machten:*:*)
+ 	echo powerpc-apple-machten${UNAME_RELEASE}
+ 	exit ;;
+     RISC*:Mach:*:*)
+ 	echo mips-dec-mach_bsd4.3
+@@ -472,31 +496,31 @@ EOF
+ 	exit ;;
+     m88k:*:4*:R4*)
+ 	echo m88k-motorola-sysv4
+ 	exit ;;
+     m88k:*:3*:R3*)
+ 	echo m88k-motorola-sysv3
+ 	exit ;;
+     AViiON:dgux:*:*)
+-        # DG/UX returns AViiON for all architectures
+-        UNAME_PROCESSOR=`/usr/bin/uname -p`
++	# DG/UX returns AViiON for all architectures
++	UNAME_PROCESSOR=`/usr/bin/uname -p`
+ 	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ 	then
+ 	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ 	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+ 	    then
+ 		echo m88k-dg-dgux${UNAME_RELEASE}
+ 	    else
+ 		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ 	    fi
+ 	else
+ 	    echo i586-dg-dgux${UNAME_RELEASE}
+ 	fi
+- 	exit ;;
++	exit ;;
+     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+ 	echo m88k-dolphin-sysv3
+ 	exit ;;
+     M88*:*:R3*:*)
+ 	# Delta 88k system running SVR3
+ 	echo m88k-motorola-sysv3
+ 	exit ;;
+     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+@@ -543,17 +567,17 @@ EOF
+ 			echo rs6000-ibm-aix3.2.5
+ 		fi
+ 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ 		echo rs6000-ibm-aix3.2.4
+ 	else
+ 		echo rs6000-ibm-aix3.2
+ 	fi
+ 	exit ;;
+-    *:AIX:*:[456])
++    *:AIX:*:[4567])
+ 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ 	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ 		IBM_ARCH=rs6000
+ 	else
+ 		IBM_ARCH=powerpc
+ 	fi
+ 	if [ -x /usr/bin/oslevel ] ; then
+ 		IBM_REV=`/usr/bin/oslevel`
+@@ -586,62 +610,62 @@ EOF
+     9000/[34678]??:HP-UX:*:*)
+ 	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ 	case "${UNAME_MACHINE}" in
+ 	    9000/31? )            HP_ARCH=m68000 ;;
+ 	    9000/[34]?? )         HP_ARCH=m68k ;;
+ 	    9000/[678][0-9][0-9])
+ 		if [ -x /usr/bin/getconf ]; then
+ 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+-                    case "${sc_cpu_version}" in
+-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+-                      532)                      # CPU_PA_RISC2_0
+-                        case "${sc_kernel_bits}" in
+-                          32) HP_ARCH="hppa2.0n" ;;
+-                          64) HP_ARCH="hppa2.0w" ;;
++		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
++		    case "${sc_cpu_version}" in
++		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
++		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
++		      532)                      # CPU_PA_RISC2_0
++			case "${sc_kernel_bits}" in
++			  32) HP_ARCH="hppa2.0n" ;;
++			  64) HP_ARCH="hppa2.0w" ;;
+ 			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+-                        esac ;;
+-                    esac
++			esac ;;
++		    esac
+ 		fi
+ 		if [ "${HP_ARCH}" = "" ]; then
+ 		    eval $set_cc_for_build
+-		    sed 's/^              //' << EOF >$dummy.c
++		    sed 's/^		//' << EOF >$dummy.c
+ 
+-              #define _HPUX_SOURCE
+-              #include <stdlib.h>
+-              #include <unistd.h>
++		#define _HPUX_SOURCE
++		#include <stdlib.h>
++		#include <unistd.h>
+ 
+-              int main ()
+-              {
+-              #if defined(_SC_KERNEL_BITS)
+-                  long bits = sysconf(_SC_KERNEL_BITS);
+-              #endif
+-                  long cpu  = sysconf (_SC_CPU_VERSION);
++		int main ()
++		{
++		#if defined(_SC_KERNEL_BITS)
++		    long bits = sysconf(_SC_KERNEL_BITS);
++		#endif
++		    long cpu  = sysconf (_SC_CPU_VERSION);
+ 
+-                  switch (cpu)
+-              	{
+-              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+-              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+-              	case CPU_PA_RISC2_0:
+-              #if defined(_SC_KERNEL_BITS)
+-              	    switch (bits)
+-              		{
+-              		case 64: puts ("hppa2.0w"); break;
+-              		case 32: puts ("hppa2.0n"); break;
+-              		default: puts ("hppa2.0"); break;
+-              		} break;
+-              #else  /* !defined(_SC_KERNEL_BITS) */
+-              	    puts ("hppa2.0"); break;
+-              #endif
+-              	default: puts ("hppa1.0"); break;
+-              	}
+-                  exit (0);
+-              }
++		    switch (cpu)
++			{
++			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
++			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
++			case CPU_PA_RISC2_0:
++		#if defined(_SC_KERNEL_BITS)
++			    switch (bits)
++				{
++				case 64: puts ("hppa2.0w"); break;
++				case 32: puts ("hppa2.0n"); break;
++				default: puts ("hppa2.0"); break;
++				} break;
++		#else  /* !defined(_SC_KERNEL_BITS) */
++			    puts ("hppa2.0"); break;
++		#endif
++			default: puts ("hppa1.0"); break;
++			}
++		    exit (0);
++		}
+ EOF
+ 		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ 		    test -z "$HP_ARCH" && HP_ARCH=hppa
+ 		fi ;;
+ 	esac
+ 	if [ ${HP_ARCH} = "hppa2.0w" ]
+ 	then
+ 	    eval $set_cc_for_build
+@@ -722,32 +746,32 @@ EOF
+ 	    echo ${UNAME_MACHINE}-unknown-osf1
+ 	fi
+ 	exit ;;
+     parisc*:Lites*:*:*)
+ 	echo hppa1.1-hp-lites
+ 	exit ;;
+     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ 	echo c1-convex-bsd
+-        exit ;;
++	exit ;;
+     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ 	if getsysinfo -f scalar_acc
+ 	then echo c32-convex-bsd
+ 	else echo c2-convex-bsd
+ 	fi
+-        exit ;;
++	exit ;;
+     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ 	echo c34-convex-bsd
+-        exit ;;
++	exit ;;
+     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ 	echo c38-convex-bsd
+-        exit ;;
++	exit ;;
+     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ 	echo c4-convex-bsd
+-        exit ;;
++	exit ;;
+     CRAY*Y-MP:*:*:*)
+ 	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ 	exit ;;
+     CRAY*[A-Z]90:*:*:*)
+ 	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ 	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ 	      -e 's/\.[^.]*$/.X/'
+@@ -761,63 +785,68 @@ EOF
+     CRAY*SV1:*:*:*)
+ 	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ 	exit ;;
+     *:UNICOS/mp:*:*)
+ 	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ 	exit ;;
+     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ 	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+-        exit ;;
++	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
++	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++	exit ;;
+     5000:UNIX_System_V:4.*:*)
+-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
++	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ 	exit ;;
+     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ 	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ 	exit ;;
+     sparc*:BSD/OS:*:*)
+ 	echo sparc-unknown-bsdi${UNAME_RELEASE}
+ 	exit ;;
+     *:BSD/OS:*:*)
+ 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ 	exit ;;
+     *:FreeBSD:*:*)
+-	case ${UNAME_MACHINE} in
+-	    pc98)
+-		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++	UNAME_PROCESSOR=`/usr/bin/uname -p`
++	case ${UNAME_PROCESSOR} in
+ 	    amd64)
+ 		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ 	    *)
+-		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ 	esac
+ 	exit ;;
+     i*:CYGWIN*:*)
+ 	echo ${UNAME_MACHINE}-pc-cygwin
+ 	exit ;;
++    *:MINGW64*:*)
++	echo ${UNAME_MACHINE}-pc-mingw64
++	exit ;;
+     *:MINGW*:*)
+ 	echo ${UNAME_MACHINE}-pc-mingw32
+ 	exit ;;
++    i*:MSYS*:*)
++	echo ${UNAME_MACHINE}-pc-msys
++	exit ;;
+     i*:windows32*:*)
+-    	# uname -m includes "-pc" on this system.
+-    	echo ${UNAME_MACHINE}-mingw32
++	# uname -m includes "-pc" on this system.
++	echo ${UNAME_MACHINE}-mingw32
+ 	exit ;;
+     i*:PW*:*)
+ 	echo ${UNAME_MACHINE}-pc-pw32
+ 	exit ;;
+-    *:Interix*:[3456]*)
+-    	case ${UNAME_MACHINE} in
++    *:Interix*:*)
++	case ${UNAME_MACHINE} in
+ 	    x86)
+ 		echo i586-pc-interix${UNAME_RELEASE}
+ 		exit ;;
+-	    EM64T | authenticamd | genuineintel)
++	    authenticamd | genuineintel | EM64T)
+ 		echo x86_64-unknown-interix${UNAME_RELEASE}
+ 		exit ;;
+ 	    IA64)
+ 		echo ia64-unknown-interix${UNAME_RELEASE}
+ 		exit ;;
+ 	esac ;;
+     [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ 	echo i${UNAME_MACHINE}-pc-mks
+@@ -840,55 +869,91 @@ EOF
+     p*:CYGWIN*:*)
+ 	echo powerpcle-unknown-cygwin
+ 	exit ;;
+     prep*:SunOS:5.*:*)
+ 	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
+     *:GNU:*:*)
+ 	# the GNU system
+-	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
++	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ 	exit ;;
+     *:GNU/*:*:*)
+ 	# other systems with GNU libc and userland
+-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
++	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ 	exit ;;
+     i*86:Minix:*:*)
+ 	echo ${UNAME_MACHINE}-pc-minix
+ 	exit ;;
++    aarch64:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    aarch64_be:Linux:*:*)
++	UNAME_MACHINE=aarch64_be
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    alpha:Linux:*:*)
++	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
++	  EV5)   UNAME_MACHINE=alphaev5 ;;
++	  EV56)  UNAME_MACHINE=alphaev56 ;;
++	  PCA56) UNAME_MACHINE=alphapca56 ;;
++	  PCA57) UNAME_MACHINE=alphapca56 ;;
++	  EV6)   UNAME_MACHINE=alphaev6 ;;
++	  EV67)  UNAME_MACHINE=alphaev67 ;;
++	  EV68*) UNAME_MACHINE=alphaev68 ;;
++	esac
++	objdump --private-headers /bin/sh | grep -q ld.so.1
++	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    arc:Linux:*:* | arceb:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
+     arm*:Linux:*:*)
+ 	eval $set_cc_for_build
+ 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ 	    | grep -q __ARM_EABI__
+ 	then
+-	    echo ${UNAME_MACHINE}-unknown-linux-gnu
++	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	else
+-	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
++		| grep -q __ARM_PCS_VFP
++	    then
++		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
++	    else
++		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
++	    fi
+ 	fi
+ 	exit ;;
+     avr32*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     cris:Linux:*:*)
+-	echo cris-axis-linux-gnu
++	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ 	exit ;;
+     crisv32:Linux:*:*)
+-	echo crisv32-axis-linux-gnu
++	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ 	exit ;;
+     frv:Linux:*:*)
+-    	echo frv-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    hexagon:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    i*86:Linux:*:*)
++	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ 	exit ;;
+     ia64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     m32r*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     m68*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     mips:Linux:*:* | mips64:Linux:*:*)
+ 	eval $set_cc_for_build
+ 	sed 's/^	//' << EOF >$dummy.c
+ 	#undef CPU
+ 	#undef ${UNAME_MACHINE}
+ 	#undef ${UNAME_MACHINE}el
+ 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+@@ -896,145 +961,87 @@ EOF
+ 	#else
+ 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ 	CPU=${UNAME_MACHINE}
+ 	#else
+ 	CPU=
+ 	#endif
+ 	#endif
+ EOF
+-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+-	    /^CPU/{
+-		s: ::g
+-		p
+-	    }'`"
+-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
++	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
++	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ 	;;
++    or1k:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
+     or32:Linux:*:*)
+-	echo or32-unknown-linux-gnu
+-	exit ;;
+-    ppc:Linux:*:*)
+-	echo powerpc-unknown-linux-gnu
+-	exit ;;
+-    ppc64:Linux:*:*)
+-	echo powerpc64-unknown-linux-gnu
+-	exit ;;
+-    alpha:Linux:*:*)
+-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+-	  EV5)   UNAME_MACHINE=alphaev5 ;;
+-	  EV56)  UNAME_MACHINE=alphaev56 ;;
+-	  PCA56) UNAME_MACHINE=alphapca56 ;;
+-	  PCA57) UNAME_MACHINE=alphapca56 ;;
+-	  EV6)   UNAME_MACHINE=alphaev6 ;;
+-	  EV67)  UNAME_MACHINE=alphaev67 ;;
+-	  EV68*) UNAME_MACHINE=alphaev68 ;;
+-        esac
+-	objdump --private-headers /bin/sh | grep -q ld.so.1
+-	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     padre:Linux:*:*)
+-	echo sparc-unknown-linux-gnu
++	echo sparc-unknown-linux-${LIBC}
++	exit ;;
++    parisc64:Linux:*:* | hppa64:Linux:*:*)
++	echo hppa64-unknown-linux-${LIBC}
+ 	exit ;;
+     parisc:Linux:*:* | hppa:Linux:*:*)
+ 	# Look for CPU level
+ 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+-	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+-	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+-	  *)    echo hppa-unknown-linux-gnu ;;
++	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
++	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
++	  *)    echo hppa-unknown-linux-${LIBC} ;;
+ 	esac
+ 	exit ;;
+-    parisc64:Linux:*:* | hppa64:Linux:*:*)
+-	echo hppa64-unknown-linux-gnu
++    ppc64:Linux:*:*)
++	echo powerpc64-unknown-linux-${LIBC}
++	exit ;;
++    ppc:Linux:*:*)
++	echo powerpc-unknown-linux-${LIBC}
++	exit ;;
++    ppc64le:Linux:*:*)
++	echo powerpc64le-unknown-linux-${LIBC}
++	exit ;;
++    ppcle:Linux:*:*)
++	echo powerpcle-unknown-linux-${LIBC}
+ 	exit ;;
+     s390:Linux:*:* | s390x:Linux:*:*)
+-	echo ${UNAME_MACHINE}-ibm-linux
++	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ 	exit ;;
+     sh64*:Linux:*:*)
+-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     sh*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     sparc:Linux:*:* | sparc64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    tile*:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     vax:Linux:*:*)
+-	echo ${UNAME_MACHINE}-dec-linux-gnu
++	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ 	exit ;;
+     x86_64:Linux:*:*)
+-	echo x86_64-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     xtensa*:Linux:*:*)
+-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+-    i*86:Linux:*:*)
+-	# The BFD linker knows what the default object file format is, so
+-	# first see if it will tell us. cd to the root directory to prevent
+-	# problems with other programs or directories called `ld' in the path.
+-	# Set LC_ALL=C to ensure ld outputs messages in English.
+-	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+-			 | sed -ne '/supported targets:/!d
+-				    s/[ 	][ 	]*/ /g
+-				    s/.*supported targets: *//
+-				    s/ .*//
+-				    p'`
+-        case "$ld_supported_targets" in
+-	  elf32-i386)
+-		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+-		;;
+-	esac
+-	# Determine whether the default compiler is a.out or elf
+-	eval $set_cc_for_build
+-	sed 's/^	//' << EOF >$dummy.c
+-	#include <features.h>
+-	#ifdef __ELF__
+-	# ifdef __GLIBC__
+-	#  if __GLIBC__ >= 2
+-	LIBC=gnu
+-	#  else
+-	LIBC=gnulibc1
+-	#  endif
+-	# else
+-	LIBC=gnulibc1
+-	# endif
+-	#else
+-	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+-	LIBC=gnu
+-	#else
+-	LIBC=gnuaout
+-	#endif
+-	#endif
+-	#ifdef __dietlibc__
+-	LIBC=dietlibc
+-	#endif
+-EOF
+-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+-	    /^LIBC/{
+-		s: ::g
+-		p
+-	    }'`"
+-	test x"${LIBC}" != x && {
+-		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+-		exit
+-	}
+-	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+-	;;
+     i*86:DYNIX/ptx:4*:*)
+ 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ 	# earlier versions are messed up and put the nodename in both
+ 	# sysname and nodename.
+ 	echo i386-sequent-sysv4
+ 	exit ;;
+     i*86:UNIX_SV:4.2MP:2.*)
+-        # Unixware is an offshoot of SVR4, but it has its own version
+-        # number series starting with 2...
+-        # I am not positive that other SVR4 systems won't match this,
++	# Unixware is an offshoot of SVR4, but it has its own version
++	# number series starting with 2...
++	# I am not positive that other SVR4 systems won't match this,
+ 	# I just have to hope.  -- rms.
+-        # Use sysv4.2uw... so that sysv4* matches it.
++	# Use sysv4.2uw... so that sysv4* matches it.
+ 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ 	exit ;;
+     i*86:OS/2:*:*)
+ 	# If we were able to find `uname', then EMX Unix compatibility
+ 	# is probably installed.
+ 	echo ${UNAME_MACHINE}-pc-os2-emx
+ 	exit ;;
+     i*86:XTS-300:*:STOP)
+@@ -1056,17 +1063,17 @@ EOF
+ 	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ 		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ 	else
+ 		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ 	fi
+ 	exit ;;
+     i*86:*:5:[678]*)
+-    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
++	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+ 	case `/bin/uname -X | grep "^Machine"` in
+ 	    *486*)	     UNAME_MACHINE=i486 ;;
+ 	    *Pentium)	     UNAME_MACHINE=i586 ;;
+ 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ 	esac
+ 	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ 	exit ;;
+     i*86:*:3.2:*)
+@@ -1084,23 +1091,23 @@ EOF
+ 			&& UNAME_MACHINE=i686
+ 		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ 	else
+ 		echo ${UNAME_MACHINE}-pc-sysv32
+ 	fi
+ 	exit ;;
+     pc:*:*:*)
+ 	# Left here for compatibility:
+-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+-        # the processor, so we play safe by assuming i586.
++	# uname -m prints for DJGPP always 'pc', but it prints nothing about
++	# the processor, so we play safe by assuming i586.
+ 	# Note: whatever this is, it MUST be the same as what config.sub
+ 	# prints for the "djgpp" host, or else GDB configury will decide that
+ 	# this is a cross-build.
+ 	echo i586-pc-msdosdjgpp
+-        exit ;;
++	exit ;;
+     Intel:Mach:3*:*)
+ 	echo i386-pc-mach3
+ 	exit ;;
+     paragon:*:*:*)
+ 	echo i860-intel-osf1
+ 	exit ;;
+     i860:*:4.*:*) # i860-SVR4
+ 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+@@ -1125,18 +1132,18 @@ EOF
+ 	OS_REL=''
+ 	test -r /etc/.relid \
+ 	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ 	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ 	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+-          && { echo i486-ncr-sysv4; exit; } ;;
++	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
++	  && { echo i486-ncr-sysv4; exit; } ;;
+     NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ 	OS_REL='.3'
+ 	test -r /etc/.relid \
+ 	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ 	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ 	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+@@ -1169,20 +1176,20 @@ EOF
+     *:SINIX-*:*:*)
+ 	if uname -p 2>/dev/null >/dev/null ; then
+ 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ 		echo ${UNAME_MACHINE}-sni-sysv4
+ 	else
+ 		echo ns32k-sni-sysv
+ 	fi
+ 	exit ;;
+-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+-                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+-        echo i586-unisys-sysv4
+-        exit ;;
++    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
++			# says <Richard.M.Bartel@ccMail.Census.GOV>
++	echo i586-unisys-sysv4
++	exit ;;
+     *:UNIX_System_V:4*:FTX*)
+ 	# From Gerald Hewes <hewes@openmarket.com>.
+ 	# How about differentiating between stratus architectures? -djm
+ 	echo hppa1.1-stratus-sysv4
+ 	exit ;;
+     *:*:*:FTX*)
+ 	# From seanf@swdc.stratus.com.
+ 	echo i860-stratus-sysv4
+@@ -1198,33 +1205,36 @@ EOF
+     mc68*:A/UX:*:*)
+ 	echo m68k-apple-aux${UNAME_RELEASE}
+ 	exit ;;
+     news*:NEWS-OS:6*:*)
+ 	echo mips-sony-newsos6
+ 	exit ;;
+     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ 	if [ -d /usr/nec ]; then
+-	        echo mips-nec-sysv${UNAME_RELEASE}
++		echo mips-nec-sysv${UNAME_RELEASE}
+ 	else
+-	        echo mips-unknown-sysv${UNAME_RELEASE}
++		echo mips-unknown-sysv${UNAME_RELEASE}
+ 	fi
+-        exit ;;
++	exit ;;
+     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+ 	echo powerpc-be-beos
+ 	exit ;;
+     BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+ 	echo powerpc-apple-beos
+ 	exit ;;
+     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+ 	echo i586-pc-beos
+ 	exit ;;
+     BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+ 	echo i586-pc-haiku
+ 	exit ;;
++    x86_64:Haiku:*:*)
++	echo x86_64-unknown-haiku
++	exit ;;
+     SX-4:SUPER-UX:*:*)
+ 	echo sx4-nec-superux${UNAME_RELEASE}
+ 	exit ;;
+     SX-5:SUPER-UX:*:*)
+ 	echo sx5-nec-superux${UNAME_RELEASE}
+ 	exit ;;
+     SX-6:SUPER-UX:*:*)
+ 	echo sx6-nec-superux${UNAME_RELEASE}
+@@ -1241,37 +1251,58 @@ EOF
+     Power*:Rhapsody:*:*)
+ 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ 	exit ;;
+     *:Rhapsody:*:*)
+ 	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ 	exit ;;
+     *:Darwin:*:*)
+ 	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+-	case $UNAME_PROCESSOR in
+-	    i386) eval $set_cc_for_build
+-	          if $CC_FOR_BUILD -E -dM -x c /dev/null | grep __LP64__>/dev/null 2>&1 ; then
+-	            UNAME_PROCESSOR=x86_64
+-	          fi ;;
+-	    unknown) UNAME_PROCESSOR=powerpc ;;
+-	esac
++	eval $set_cc_for_build
++	if test "$UNAME_PROCESSOR" = unknown ; then
++	    UNAME_PROCESSOR=powerpc
++	fi
++	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
++	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
++		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++		    grep IS_64BIT_ARCH >/dev/null
++		then
++		    case $UNAME_PROCESSOR in
++			i386) UNAME_PROCESSOR=x86_64 ;;
++			powerpc) UNAME_PROCESSOR=powerpc64 ;;
++		    esac
++		fi
++	    fi
++	elif test "$UNAME_PROCESSOR" = i386 ; then
++	    # Avoid executing cc on OS X 10.9, as it ships with a stub
++	    # that puts up a graphical alert prompting to install
++	    # developer tools.  Any system running Mac OS X 10.7 or
++	    # later (Darwin 11 and later) is required to have a 64-bit
++	    # processor. This is not true of the ARM version of Darwin
++	    # that Apple uses in portable devices.
++	    UNAME_PROCESSOR=x86_64
++	fi
+ 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ 	exit ;;
+     *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ 	UNAME_PROCESSOR=`uname -p`
+ 	if test "$UNAME_PROCESSOR" = "x86"; then
+ 		UNAME_PROCESSOR=i386
+ 		UNAME_MACHINE=pc
+ 	fi
+ 	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ 	exit ;;
+     *:QNX:*:4*)
+ 	echo i386-pc-qnx
+ 	exit ;;
+-    NSE-?:NONSTOP_KERNEL:*:*)
++    NEO-?:NONSTOP_KERNEL:*:*)
++	echo neo-tandem-nsk${UNAME_RELEASE}
++	exit ;;
++    NSE-*:NONSTOP_KERNEL:*:*)
+ 	echo nse-tandem-nsk${UNAME_RELEASE}
+ 	exit ;;
+     NSR-?:NONSTOP_KERNEL:*:*)
+ 	echo nsr-tandem-nsk${UNAME_RELEASE}
+ 	exit ;;
+     *:NonStop-UX:*:*)
+ 	echo mips-compaq-nonstopux
+ 	exit ;;
+@@ -1306,23 +1337,23 @@ EOF
+ 	exit ;;
+     *:TOPS-20:*:*)
+ 	echo pdp10-unknown-tops20
+ 	exit ;;
+     *:ITS:*:*)
+ 	echo pdp10-unknown-its
+ 	exit ;;
+     SEI:*:*:SEIUX)
+-        echo mips-sei-seiux${UNAME_RELEASE}
++	echo mips-sei-seiux${UNAME_RELEASE}
+ 	exit ;;
+     *:DragonFly:*:*)
+ 	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ 	exit ;;
+     *:*VMS:*:*)
+-    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
++	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ 	case "${UNAME_MACHINE}" in
+ 	    A*) echo alpha-dec-vms ; exit ;;
+ 	    I*) echo ia64-dec-vms ; exit ;;
+ 	    V*) echo vax-dec-vms ; exit ;;
+ 	esac ;;
+     *:XENIX:*:SysV)
+ 	echo i386-pc-xenix
+ 	exit ;;
+@@ -1330,169 +1361,21 @@ EOF
+ 	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ 	exit ;;
+     i*86:rdos:*:*)
+ 	echo ${UNAME_MACHINE}-pc-rdos
+ 	exit ;;
+     i*86:AROS:*:*)
+ 	echo ${UNAME_MACHINE}-pc-aros
+ 	exit ;;
++    x86_64:VMkernel:*:*)
++	echo ${UNAME_MACHINE}-unknown-esx
++	exit ;;
+ esac
+ 
+-#echo '(No uname command or uname output not recognized.)' 1>&2
+-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+-
+-eval $set_cc_for_build
+-cat >$dummy.c <<EOF
+-#ifdef _SEQUENT_
+-# include <sys/types.h>
+-# include <sys/utsname.h>
+-#endif
+-main ()
+-{
+-#if defined (sony)
+-#if defined (MIPSEB)
+-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+-     I don't know....  */
+-  printf ("mips-sony-bsd\n"); exit (0);
+-#else
+-#include <sys/param.h>
+-  printf ("m68k-sony-newsos%s\n",
+-#ifdef NEWSOS4
+-          "4"
+-#else
+-	  ""
+-#endif
+-         ); exit (0);
+-#endif
+-#endif
+-
+-#if defined (__arm) && defined (__acorn) && defined (__unix)
+-  printf ("arm-acorn-riscix\n"); exit (0);
+-#endif
+-
+-#if defined (hp300) && !defined (hpux)
+-  printf ("m68k-hp-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (NeXT)
+-#if !defined (__ARCHITECTURE__)
+-#define __ARCHITECTURE__ "m68k"
+-#endif
+-  int version;
+-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+-  if (version < 4)
+-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+-  else
+-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+-  exit (0);
+-#endif
+-
+-#if defined (MULTIMAX) || defined (n16)
+-#if defined (UMAXV)
+-  printf ("ns32k-encore-sysv\n"); exit (0);
+-#else
+-#if defined (CMU)
+-  printf ("ns32k-encore-mach\n"); exit (0);
+-#else
+-  printf ("ns32k-encore-bsd\n"); exit (0);
+-#endif
+-#endif
+-#endif
+-
+-#if defined (__386BSD__)
+-  printf ("i386-pc-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (sequent)
+-#if defined (i386)
+-  printf ("i386-sequent-dynix\n"); exit (0);
+-#endif
+-#if defined (ns32000)
+-  printf ("ns32k-sequent-dynix\n"); exit (0);
+-#endif
+-#endif
+-
+-#if defined (_SEQUENT_)
+-    struct utsname un;
+-
+-    uname(&un);
+-
+-    if (strncmp(un.version, "V2", 2) == 0) {
+-	printf ("i386-sequent-ptx2\n"); exit (0);
+-    }
+-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+-	printf ("i386-sequent-ptx1\n"); exit (0);
+-    }
+-    printf ("i386-sequent-ptx\n"); exit (0);
+-
+-#endif
+-
+-#if defined (vax)
+-# if !defined (ultrix)
+-#  include <sys/param.h>
+-#  if defined (BSD)
+-#   if BSD == 43
+-      printf ("vax-dec-bsd4.3\n"); exit (0);
+-#   else
+-#    if BSD == 199006
+-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+-#    else
+-      printf ("vax-dec-bsd\n"); exit (0);
+-#    endif
+-#   endif
+-#  else
+-    printf ("vax-dec-bsd\n"); exit (0);
+-#  endif
+-# else
+-    printf ("vax-dec-ultrix\n"); exit (0);
+-# endif
+-#endif
+-
+-#if defined (alliant) && defined (i860)
+-  printf ("i860-alliant-bsd\n"); exit (0);
+-#endif
+-
+-  exit (1);
+-}
+-EOF
+-
+-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+-	{ echo "$SYSTEM_NAME"; exit; }
+-
+-# Apollos put the system type in the environment.
+-
+-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+-
+-# Convex versions that predate uname can use getsysinfo(1)
+-
+-if [ -x /usr/convex/getsysinfo ]
+-then
+-    case `getsysinfo -f cpu_type` in
+-    c1*)
+-	echo c1-convex-bsd
+-	exit ;;
+-    c2*)
+-	if getsysinfo -f scalar_acc
+-	then echo c32-convex-bsd
+-	else echo c2-convex-bsd
+-	fi
+-	exit ;;
+-    c34*)
+-	echo c34-convex-bsd
+-	exit ;;
+-    c38*)
+-	echo c38-convex-bsd
+-	exit ;;
+-    c4*)
+-	echo c4-convex-bsd
+-	exit ;;
+-    esac
+-fi
+-
+ cat >&2 <<EOF
+ $0: unable to guess system type
+ 
+ This script, last modified $timestamp, has failed to recognize
+ the operating system you are using. It is advised that you
+ download the most up to date version of the config scripts from
+ 
+   http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+diff --git a/build/autoconf/config.sub b/build/autoconf/config.sub
+--- a/build/autoconf/config.sub
++++ b/build/autoconf/config.sub
+@@ -1,43 +1,36 @@
+ #! /bin/sh
+ # Configuration validation subroutine script.
+-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-#   Free Software Foundation, Inc.
++#   Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+-timestamp='2011-01-03'
++timestamp='2014-01-01'
+ 
+-# This file is (in principle) common to ALL GNU software.
+-# The presence of a machine in this file suggests that SOME GNU software
+-# can handle that machine.  It does not imply ALL GNU software can.
+-#
+-# This file is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# This file is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU General Public License for more details.
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++# General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
++# the same distribution terms that you use for the rest of that
++# program.  This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ 
+ 
+-# Please send patches to <config-patches@gnu.org>.  Submit a context
+-# diff and a properly formatted GNU ChangeLog entry.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+ # If it is invalid, we print an error message on stderr and exit with code 1.
+ # Otherwise, we print the canonical config type on stdout and succeed.
+ 
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+@@ -70,18 +63,17 @@ Operation modes:
+   -t, --time-stamp   print date of last modification, then exit
+   -v, --version      print version number, then exit
+ 
+ Report bugs and patches to <config-patches@gnu.org>."
+ 
+ version="\
+ GNU config.sub ($timestamp)
+ 
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+ This is free software; see the source for copying conditions.  There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+ 
+ help="
+ Try \`$me --help' for more information."
+ 
+ # Parse command line
+@@ -118,23 +110,28 @@ case $# in
+  *) echo "$me: too many arguments$help" >&2
+     exit 1;;
+ esac
+ 
+ # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+ # Here we must recognize all the valid KERNEL-OS combinations.
+ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ case $maybe_os in
+-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
++  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
++  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
++  knetbsd*-gnu* | netbsd*-gnu* | \
+   kopensolaris*-gnu* | \
+-  storm-chaos* | os2-emx* | rtmk-nova* | wince-winmo*)
++  storm-chaos* | os2-emx* | rtmk-nova*)
+     os=-$maybe_os
+     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+     ;;
++  android-linux)
++    os=-linux-android
++    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
++    ;;
+   *)
+     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+     if [ $basic_machine != $1 ]
+     then os=`echo $1 | sed 's/.*-/-/'`
+     else os=; fi
+     ;;
+ esac
+ 
+@@ -147,41 +144,41 @@ case $os in
+ 		# Prevent following clause from handling this invalid input.
+ 		;;
+ 	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ 	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ 	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+-	-apple | -axis | -knuth | -cray | -microblaze)
++	-apple | -axis | -knuth | -cray | -microblaze*)
+ 		os=
+ 		basic_machine=$1
+ 		;;
+-        -bluegene*)
+-	        os=-cnk
++	-bluegene*)
++		os=-cnk
+ 		;;
+ 	-sim | -cisco | -oki | -wec | -winbond)
+ 		os=
+ 		basic_machine=$1
+ 		;;
+ 	-scout)
+ 		;;
+ 	-wrs)
+ 		os=-vxworks
+ 		basic_machine=$1
+ 		;;
+ 	-chorusos*)
+ 		os=-chorusos
+ 		basic_machine=$1
+ 		;;
+- 	-chorusrdb)
+- 		os=-chorusrdb
++	-chorusrdb)
++		os=-chorusrdb
+ 		basic_machine=$1
+- 		;;
++		;;
+ 	-hiux*)
+ 		os=-hiuxwe2
+ 		;;
+ 	-sco6)
+ 		os=-sco5v6
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ 		;;
+ 	-sco5)
+@@ -216,16 +213,22 @@ case $os in
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ 		;;
+ 	-clix*)
+ 		basic_machine=clipper-intergraph
+ 		;;
+ 	-isc*)
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ 		;;
++	-lynx*178)
++		os=-lynxos178
++		;;
++	-lynx*5)
++		os=-lynxos5
++		;;
+ 	-lynx*)
+ 		os=-lynxos
+ 		;;
+ 	-ptx*)
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ 		;;
+ 	-windowsnt*)
+ 		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+@@ -240,30 +243,38 @@ case $os in
+ esac
+ 
+ # Decode aliases for certain CPU-COMPANY combinations.
+ case $basic_machine in
+ 	# Recognize the basic CPU types without company name.
+ 	# Some are omitted here because they have special meanings below.
+ 	1750a | 580 \
+ 	| a29k \
++	| aarch64 | aarch64_be \
+ 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ 	| am33_2.0 \
+-	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
++	| arc | arceb \
++	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
++	| avr | avr32 \
++	| be32 | be64 \
+ 	| bfin \
+-	| c4x | clipper \
++	| c4x | c8051 | clipper \
+ 	| d10v | d30v | dlx | dsp16xx \
++	| epiphany \
+ 	| fido | fr30 | frv \
+ 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
++	| hexagon \
+ 	| i370 | i860 | i960 | ia64 \
+ 	| ip2k | iq2000 \
++	| k1om \
++	| le32 | le64 \
+ 	| lm32 \
+ 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+-	| maxq | mb | microblaze | mcore | mep | metag \
++	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ 	| mips | mipsbe | mipseb | mipsel | mipsle \
+ 	| mips16 \
+ 	| mips64 | mips64el \
+ 	| mips64octeon | mips64octeonel \
+ 	| mips64orion | mips64orionel \
+ 	| mips64r5900 | mips64r5900el \
+ 	| mips64vr | mips64vrel \
+ 	| mips64vr4100 | mips64vr4100el \
+@@ -271,84 +282,118 @@ case $basic_machine in
+ 	| mips64vr5000 | mips64vr5000el \
+ 	| mips64vr5900 | mips64vr5900el \
+ 	| mipsisa32 | mipsisa32el \
+ 	| mipsisa32r2 | mipsisa32r2el \
+ 	| mipsisa64 | mipsisa64el \
+ 	| mipsisa64r2 | mipsisa64r2el \
+ 	| mipsisa64sb1 | mipsisa64sb1el \
+ 	| mipsisa64sr71k | mipsisa64sr71kel \
++	| mipsr5900 | mipsr5900el \
+ 	| mipstx39 | mipstx39el \
+ 	| mn10200 | mn10300 \
+ 	| moxie \
+ 	| mt \
+ 	| msp430 \
+-	| nios | nios2 \
++	| nds32 | nds32le | nds32be \
++	| nios | nios2 | nios2eb | nios2el \
+ 	| ns16k | ns32k \
+-	| or32 \
++	| open8 \
++	| or1k | or32 \
+ 	| pdp10 | pdp11 | pj | pjl \
+-	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
++	| powerpc | powerpc64 | powerpc64le | powerpcle \
+ 	| pyramid \
++	| rl78 | rx \
+ 	| score \
+ 	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ 	| sh64 | sh64le \
+ 	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ 	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+-	| spu | strongarm \
+-	| tahoe | thumb | tic4x | tic80 | tron \
+-	| v850 | v850e \
++	| spu \
++	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
++	| ubicom32 \
++	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ 	| we32k \
+-	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
++	| x86 | xc16x | xstormy16 | xtensa \
+ 	| z8k | z80)
+ 		basic_machine=$basic_machine-unknown
+ 		;;
+-	m6811 | m68hc11 | m6812 | m68hc12)
+-		# Motorola 68HC11/12.
++	c54x)
++		basic_machine=tic54x-unknown
++		;;
++	c55x)
++		basic_machine=tic55x-unknown
++		;;
++	c6x)
++		basic_machine=tic6x-unknown
++		;;
++	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ 		basic_machine=$basic_machine-unknown
+ 		os=-none
+ 		;;
+ 	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ 		;;
+ 	ms1)
+ 		basic_machine=mt-unknown
+ 		;;
+ 
++	strongarm | thumb | xscale)
++		basic_machine=arm-unknown
++		;;
++	xgate)
++		basic_machine=$basic_machine-unknown
++		os=-none
++		;;
++	xscaleeb)
++		basic_machine=armeb-unknown
++		;;
++
++	xscaleel)
++		basic_machine=armel-unknown
++		;;
++
+ 	# We use `pc' rather than `unknown'
+ 	# because (1) that's what they normally are, and
+ 	# (2) the word "unknown" tends to confuse beginning users.
+ 	i*86 | x86_64)
+ 	  basic_machine=$basic_machine-pc
+ 	  ;;
+ 	# Object if more than one company name word.
+ 	*-*-*)
+ 		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ 		exit 1
+ 		;;
+ 	# Recognize the basic CPU types with company name.
+ 	580-* \
+ 	| a29k-* \
++	| aarch64-* | aarch64_be-* \
+ 	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
++	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+ 	| avr-* | avr32-* \
++	| be32-* | be64-* \
+ 	| bfin-* | bs2000-* \
+-	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+-	| clipper-* | craynv-* | cydra-* \
++	| c[123]* | c30-* | [cjt]90-* | c4x-* \
++	| c8051-* | clipper-* | craynv-* | cydra-* \
+ 	| d10v-* | d30v-* | dlx-* \
+ 	| elxsi-* \
+ 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ 	| h8300-* | h8500-* \
+ 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
++	| hexagon-* \
+ 	| i*86-* | i860-* | i960-* | ia64-* \
+ 	| ip2k-* | iq2000-* \
++	| k1om-* \
++	| le32-* | le64-* \
+ 	| lm32-* \
+ 	| m32c-* | m32r-* | m32rle-* \
+ 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
++	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
++	| microblaze-* | microblazeel-* \
+ 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ 	| mips16-* \
+ 	| mips64-* | mips64el-* \
+ 	| mips64octeon-* | mips64octeonel-* \
+ 	| mips64orion-* | mips64orionel-* \
+ 	| mips64r5900-* | mips64r5900el-* \
+ 	| mips64vr-* | mips64vrel-* \
+ 	| mips64vr4100-* | mips64vr4100el-* \
+@@ -356,38 +401,44 @@ case $basic_machine in
+ 	| mips64vr5000-* | mips64vr5000el-* \
+ 	| mips64vr5900-* | mips64vr5900el-* \
+ 	| mipsisa32-* | mipsisa32el-* \
+ 	| mipsisa32r2-* | mipsisa32r2el-* \
+ 	| mipsisa64-* | mipsisa64el-* \
+ 	| mipsisa64r2-* | mipsisa64r2el-* \
+ 	| mipsisa64sb1-* | mipsisa64sb1el-* \
+ 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
++	| mipsr5900-* | mipsr5900el-* \
+ 	| mipstx39-* | mipstx39el-* \
+ 	| mmix-* \
+ 	| mt-* \
+ 	| msp430-* \
+-	| nios-* | nios2-* \
++	| nds32-* | nds32le-* | nds32be-* \
++	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+ 	| none-* | np1-* | ns16k-* | ns32k-* \
++	| open8-* \
+ 	| orion-* \
+ 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
++	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ 	| pyramid-* \
+-	| romp-* | rs6000-* \
++	| rl78-* | romp-* | rs6000-* | rx-* \
+ 	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ 	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ 	| sparclite-* \
+-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+-	| tahoe-* | thumb-* \
+-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
++	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
++	| tahoe-* \
++	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
++	| tile*-* \
+ 	| tron-* \
+-	| v850-* | v850e-* | vax-* \
++	| ubicom32-* \
++	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
++	| vax-* \
+ 	| we32k-* \
+-	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
++	| x86-* | x86_64-* | xc16x-* | xps100-* \
+ 	| xstormy16-* | xtensa*-* \
+ 	| ymp-* \
+ 	| z8k-* | z80-*)
+ 		;;
+ 	# Recognize the basic CPU types without company name, with glob match.
+ 	xtensa*)
+ 		basic_machine=$basic_machine-unknown
+ 		;;
+@@ -402,17 +453,17 @@ case $basic_machine in
+ 		;;
+ 	3b*)
+ 		basic_machine=we32k-att
+ 		;;
+ 	a29khif)
+ 		basic_machine=a29k-amd
+ 		os=-udi
+ 		;;
+-    	abacus)
++	abacus)
+ 		basic_machine=abacus-unknown
+ 		;;
+ 	adobe68k)
+ 		basic_machine=m68010-adobe
+ 		os=-scout
+ 		;;
+ 	alliant | fx80)
+ 		basic_machine=fx80-alliant
+@@ -472,21 +523,30 @@ case $basic_machine in
+ 	blackfin-*)
+ 		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		os=-linux
+ 		;;
+ 	bluegene*)
+ 		basic_machine=powerpc-ibm
+ 		os=-cnk
+ 		;;
++	c54x-*)
++		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
++	c55x-*)
++		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
++	c6x-*)
++		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
+ 	c90)
+ 		basic_machine=c90-cray
+ 		os=-unicos
+ 		;;
+-        cegcc)
++	cegcc)
+ 		basic_machine=arm-unknown
+ 		os=-cegcc
+ 		;;
+ 	convex-c1)
+ 		basic_machine=c1-convex
+ 		os=-bsd
+ 		;;
+ 	convex-c2)
+@@ -508,17 +568,17 @@ case $basic_machine in
+ 	cray | j90)
+ 		basic_machine=j90-cray
+ 		os=-unicos
+ 		;;
+ 	craynv)
+ 		basic_machine=craynv-cray
+ 		os=-unicosmp
+ 		;;
+-	cr16)
++	cr16 | cr16-*)
+ 		basic_machine=cr16-unknown
+ 		os=-elf
+ 		;;
+ 	crds | unos)
+ 		basic_machine=m68k-crds
+ 		;;
+ 	crisv32 | crisv32-* | etraxfs*)
+ 		basic_machine=crisv32-axis
+@@ -666,17 +726,16 @@ case $basic_machine in
+ 		;;
+ 	hppro)
+ 		basic_machine=hppa1.1-hp
+ 		os=-proelf
+ 		;;
+ 	i370-ibm* | ibm*)
+ 		basic_machine=i370-ibm
+ 		;;
+-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+ 	i*86v32)
+ 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ 		os=-sysv32
+ 		;;
+ 	i*86v4*)
+ 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ 		os=-sysv4
+ 		;;
+@@ -724,21 +783,25 @@ case $basic_machine in
+ 	magnum | m3230)
+ 		basic_machine=mips-mips
+ 		os=-sysv
+ 		;;
+ 	merlin)
+ 		basic_machine=ns32k-utek
+ 		os=-sysv
+ 		;;
+-        microblaze)
++	microblaze*)
+ 		basic_machine=microblaze-xilinx
+ 		;;
++	mingw64)
++		basic_machine=x86_64-pc
++		os=-mingw64
++		;;
+ 	mingw32)
+-		basic_machine=i386-pc
++		basic_machine=i686-pc
+ 		os=-mingw32
+ 		;;
+ 	mingw32ce)
+ 		basic_machine=arm-unknown
+ 		os=-mingw32ce
+ 		;;
+ 	miniframe)
+ 		basic_machine=m68000-convergent
+@@ -763,20 +826,28 @@ case $basic_machine in
+ 		;;
+ 	msdos)
+ 		basic_machine=i386-pc
+ 		os=-msdos
+ 		;;
+ 	ms1-*)
+ 		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ 		;;
++	msys)
++		basic_machine=i686-pc
++		os=-msys
++		;;
+ 	mvs)
+ 		basic_machine=i370-ibm
+ 		os=-mvs
+ 		;;
++	nacl)
++		basic_machine=le32-unknown
++		os=-nacl
++		;;
+ 	ncr3000)
+ 		basic_machine=i486-ncr
+ 		os=-sysv4
+ 		;;
+ 	netbsd386)
+ 		basic_machine=i386-unknown
+ 		os=-netbsd
+ 		;;
+@@ -831,16 +902,22 @@ case $basic_machine in
+ 		;;
+ 	nonstopux)
+ 		basic_machine=mips-compaq
+ 		os=-nonstopux
+ 		;;
+ 	np1)
+ 		basic_machine=np1-gould
+ 		;;
++	neo-tandem)
++		basic_machine=neo-tandem
++		;;
++	nse-tandem)
++		basic_machine=nse-tandem
++		;;
+ 	nsr-tandem)
+ 		basic_machine=nsr-tandem
+ 		;;
+ 	op50n-* | op60c-*)
+ 		basic_machine=hppa1.1-oki
+ 		os=-proelf
+ 		;;
+ 	openrisc | openrisc-*)
+@@ -913,19 +990,20 @@ case $basic_machine in
+ 	pentium4-*)
+ 		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		;;
+ 	pn)
+ 		basic_machine=pn-gould
+ 		;;
+ 	power)	basic_machine=power-ibm
+ 		;;
+-	ppc)	basic_machine=powerpc-unknown
++	ppc | ppcbe)	basic_machine=powerpc-unknown
+ 		;;
+-	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
++	ppc-* | ppcbe-*)
++		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		;;
+ 	ppcle | powerpclittle | ppc-le | powerpc-little)
+ 		basic_machine=powerpcle-unknown
+ 		;;
+ 	ppcle-* | powerpclittle-*)
+ 		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		;;
+ 	ppc64)	basic_machine=powerpc64-unknown
+@@ -940,17 +1018,21 @@ case $basic_machine in
+ 		;;
+ 	ps2)
+ 		basic_machine=i386-ibm
+ 		;;
+ 	pw32)
+ 		basic_machine=i586-unknown
+ 		os=-pw32
+ 		;;
+-	rdos)
++	rdos | rdos64)
++		basic_machine=x86_64-pc
++		os=-rdos
++		;;
++	rdos32)
+ 		basic_machine=i386-pc
+ 		os=-rdos
+ 		;;
+ 	rom68k)
+ 		basic_machine=m68k-rom68k
+ 		os=-coff
+ 		;;
+ 	rm[46]00)
+@@ -1009,16 +1091,19 @@ case $basic_machine in
+ 		;;
+ 	st2000)
+ 		basic_machine=m68k-tandem
+ 		;;
+ 	stratus)
+ 		basic_machine=i860-stratus
+ 		os=-sysv4
+ 		;;
++	strongarm-* | thumb-*)
++		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
+ 	sun2)
+ 		basic_machine=m68000-sun
+ 		;;
+ 	sun2os3)
+ 		basic_machine=m68000-sun
+ 		os=-sunos3
+ 		;;
+ 	sun2os4)
+@@ -1065,30 +1150,18 @@ case $basic_machine in
+ 	t3e)
+ 		basic_machine=alphaev5-cray
+ 		os=-unicos
+ 		;;
+ 	t90)
+ 		basic_machine=t90-cray
+ 		os=-unicos
+ 		;;
+-	tic54x | c54x*)
+-		basic_machine=tic54x-unknown
+-		os=-coff
+-		;;
+-	tic55x | c55x*)
+-		basic_machine=tic55x-unknown
+-		os=-coff
+-		;;
+-	tic6x | c6x*)
+-		basic_machine=tic6x-unknown
+-		os=-coff
+-		;;
+ 	tile*)
+-		basic_machine=tile-unknown
++		basic_machine=$basic_machine-unknown
+ 		os=-linux-gnu
+ 		;;
+ 	tx39)
+ 		basic_machine=mipstx39-unknown
+ 		;;
+ 	tx39el)
+ 		basic_machine=mipstx39el-unknown
+ 		;;
+@@ -1148,16 +1221,19 @@ case $basic_machine in
+ 		;;
+ 	xbox)
+ 		basic_machine=i686-pc
+ 		os=-mingw32
+ 		;;
+ 	xps | xps100)
+ 		basic_machine=xps100-honeywell
+ 		;;
++	xscale-* | xscalee[bl]-*)
++		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
++		;;
+ 	ymp)
+ 		basic_machine=ymp-cray
+ 		os=-unicos
+ 		;;
+ 	z8k-*-coff)
+ 		basic_machine=z8k-unknown
+ 		os=-sim
+ 		;;
+@@ -1245,19 +1321,22 @@ case $basic_machine in
+ 		;;
+ esac
+ 
+ # Decode manufacturer-specific aliases for certain operating systems.
+ 
+ if [ x"$os" != x"" ]
+ then
+ case $os in
+-        # First match some system type aliases
+-        # that might get confused with valid system types.
++	# First match some system type aliases
++	# that might get confused with valid system types.
+ 	# -solaris* is a basic system type, with this one exception.
++	-auroraux)
++		os=-auroraux
++		;;
+ 	-solaris1 | -solaris1.*)
+ 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ 		;;
+ 	-solaris)
+ 		os=-solaris2
+ 		;;
+ 	-svr4*)
+ 		os=-sysv4
+@@ -1269,39 +1348,40 @@ case $os in
+ 		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ 		;;
+ 	# First accept the basic system types.
+ 	# The portable systems comes first.
+ 	# Each alternative MUST END IN A *, to match a version number.
+ 	# -sysv* is not here because it comes later, after sysvr4.
+ 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ 	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+-	      | -kopensolaris* \
++	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
++	      | -sym* | -kopensolaris* | -plan9* \
+ 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ 	      | -aos* | -aros* \
+ 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+-	      | -openbsd* | -solidbsd* \
++	      | -bitrig* | -openbsd* | -solidbsd* \
+ 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ 	      | -chorusos* | -chorusrdb* | -cegcc* \
+-	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+-	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
++	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
++	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
++	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ 	      | -uxpv* | -beos* | -mpeix* | -udk* \
+ 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -winmo*)
++	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ 	# Remember, each alternative MUST END IN *, to match a version number.
+ 		;;
+ 	-qnx*)
+ 		case $basic_machine in
+ 		    x86-* | i*86-*)
+ 			;;
+ 		    *)
+ 			os=-nto$os
+@@ -1330,22 +1410,19 @@ case $os in
+ 		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ 		;;
+ 	-sunos6*)
+ 		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ 		;;
+ 	-opened*)
+ 		os=-openedition
+ 		;;
+-        -os400*)
++	-os400*)
+ 		os=-os400
+ 		;;
+-	-wince-winmo*)
+-		os=-wince-winmo
+-		;;
+ 	-wince*)
+ 		os=-wince
+ 		;;
+ 	-osfrose*)
+ 		os=-osfrose
+ 		;;
+ 	-osf*)
+ 		os=-osf
+@@ -1382,17 +1459,17 @@ case $os in
+ 		;;
+ 	# Preserve the version number of sinix5.
+ 	-sinix5.*)
+ 		os=`echo $os | sed -e 's|sinix|sysv|'`
+ 		;;
+ 	-sinix*)
+ 		os=-sysv4
+ 		;;
+-        -tpf*)
++	-tpf*)
+ 		os=-tpf
+ 		;;
+ 	-triton*)
+ 		os=-sysv3
+ 		;;
+ 	-oss*)
+ 		os=-sysv3
+ 		;;
+@@ -1418,28 +1495,24 @@ case $os in
+ 		os=-xenix
+ 		;;
+ 	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ 		os=-mint
+ 		;;
+ 	-aros*)
+ 		os=-aros
+ 		;;
+-	-kaos*)
+-		os=-kaos
+-		;;
+ 	-zvmoe)
+ 		os=-zvmoe
+ 		;;
+ 	-dicos*)
+ 		os=-dicos
+ 		;;
+-        -android*)
+-	        os=-android
+-                ;;
++	-nacl*)
++		;;
+ 	-none)
+ 		;;
+ 	*)
+ 		# Get rid of the `-' at the beginning of $os.
+ 		os=`echo $os | sed 's/[^-]*-//'`
+ 		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ 		exit 1
+ 		;;
+@@ -1452,33 +1525,48 @@ else
+ 
+ # Note that if you're going to try to match "-MANUFACTURER" here (say,
+ # "-sun"), then you have to tell the case statement up towards the top
+ # that MANUFACTURER isn't an operating system.  Otherwise, code above
+ # will signal an error saying that MANUFACTURER isn't an operating
+ # system, and we'll never get to this point.
+ 
+ case $basic_machine in
+-        score-*)
++	score-*)
+ 		os=-elf
+ 		;;
+-        spu-*)
++	spu-*)
+ 		os=-elf
+ 		;;
+ 	*-acorn)
+ 		os=-riscix1.2
+ 		;;
+ 	arm*-rebel)
+ 		os=-linux
+ 		;;
+ 	arm*-semi)
+ 		os=-aout
+ 		;;
+-        c4x-* | tic4x-*)
+-        	os=-coff
++	c4x-* | tic4x-*)
++		os=-coff
++		;;
++	c8051-*)
++		os=-elf
++		;;
++	hexagon-*)
++		os=-elf
++		;;
++	tic54x-*)
++		os=-coff
++		;;
++	tic55x-*)
++		os=-coff
++		;;
++	tic6x-*)
++		os=-coff
+ 		;;
+ 	# This must come before the *-dec entry.
+ 	pdp10-*)
+ 		os=-tops20
+ 		;;
+ 	pdp11-*)
+ 		os=-none
+ 		;;
+@@ -1488,32 +1576,32 @@ case $basic_machine in
+ 	m68*-apollo)
+ 		os=-domain
+ 		;;
+ 	i386-sun)
+ 		os=-sunos4.0.2
+ 		;;
+ 	m68000-sun)
+ 		os=-sunos3
+-		# This also exists in the configure program, but was not the
+-		# default.
+-		# os=-sunos4
+ 		;;
+ 	m68*-cisco)
+ 		os=-aout
+ 		;;
+-        mep-*)
++	mep-*)
+ 		os=-elf
+ 		;;
+ 	mips*-cisco)
+ 		os=-elf
+ 		;;
+ 	mips*-*)
+ 		os=-elf
+ 		;;
++	or1k-*)
++		os=-elf
++		;;
+ 	or32-*)
+ 		os=-coff
+ 		;;
+ 	*-tti)	# must be before sparc entry or we get the wrong os.
+ 		os=-sysv3
+ 		;;
+ 	sparc-* | *-sun)
+ 		os=-sunos4.1.1
+@@ -1522,17 +1610,17 @@ case $basic_machine in
+ 		os=-beos
+ 		;;
+ 	*-haiku)
+ 		os=-haiku
+ 		;;
+ 	*-ibm)
+ 		os=-aix
+ 		;;
+-    	*-knuth)
++	*-knuth)
+ 		os=-mmixware
+ 		;;
+ 	*-wec)
+ 		os=-proelf
+ 		;;
+ 	*-winbond)
+ 		os=-proelf
+ 		;;
+@@ -1684,19 +1772,16 @@ case $basic_machine in
+ 				vendor=apple
+ 				;;
+ 			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ 				vendor=atari
+ 				;;
+ 			-vos*)
+ 				vendor=stratus
+ 				;;
+-			*-android*|*-linuxandroid*)
+-				vendor=linux-
+-				;;
+ 		esac
+ 		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ 		;;
+ esac
+ 
+ echo $basic_machine$os
+ exit
+ 
+diff --git a/configure.in b/configure.in
+--- a/configure.in
++++ b/configure.in
+@@ -1082,17 +1082,17 @@ esac
+ 
+ # Only set CPU_ARCH if we recognize the value of OS_TEST
+ 
+ case "$OS_TEST" in
+ *86 | i86pc)
+     CPU_ARCH=x86
+     ;;
+ 
+-powerpc64 | ppc64)
++powerpc64 | ppc64 | powerpc64le | ppc64le)
+     CPU_ARCH=ppc64
+     ;;
+ 
+ powerpc | ppc | rs6000)
+     CPU_ARCH=ppc
+     ;;
+ 
+ Alpha | alpha | ALPHA)
+diff --git a/js/src/build/autoconf/config.guess b/js/src/build/autoconf/config.guess
+--- a/js/src/build/autoconf/config.guess
++++ b/js/src/build/autoconf/config.guess
+@@ -1,47 +1,41 @@
+ #! /bin/sh
+ # Attempt to guess a canonical system name.
+-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-#   Free Software Foundation, Inc.
++#   Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+-timestamp='2009-08-19'
++timestamp='2014-02-12'
+ 
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ # General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
+-
+-
+-# Originally written by Per Bothner.  Please send patches (context
+-# diff format) to <config-patches@gnu.org> and include a ChangeLog
+-# entry.
++# the same distribution terms that you use for the rest of that
++# program.  This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ #
+-# This script attempts to guess a canonical system name similar to
+-# config.sub.  If it succeeds, it prints the system name on stdout, and
+-# exits with 0.  Otherwise, it exits with 1.
++# Originally written by Per Bothner.
+ #
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++#
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++
+ 
+ me=`echo "$0" | sed -e 's,.*/,,'`
+ 
+ usage="\
+ Usage: $0 [OPTION]
+ 
+ Output the configuration name of the system \`$me' is run on.
+ 
+@@ -51,18 +45,17 @@ Operation modes:
+   -v, --version      print version number, then exit
+ 
+ Report bugs and patches to <config-patches@gnu.org>."
+ 
+ version="\
+ GNU config.guess ($timestamp)
+ 
+ Originally written by Per Bothner.
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+ This is free software; see the source for copying conditions.  There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+ 
+ help="
+ Try \`$me --help' for more information."
+ 
+ # Parse command line
+@@ -134,22 +127,43 @@ if (test -f /.attbin/uname) >/dev/null 2
+ 	PATH=$PATH:/.attbin ; export PATH
+ fi
+ 
+ UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+ UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+ 
++case "${UNAME_SYSTEM}" in
++Linux|GNU|GNU/*)
++	# If the system lacks a compiler, then just pick glibc.
++	# We could probably try harder.
++	LIBC=gnu
++
++	eval $set_cc_for_build
++	cat <<-EOF > $dummy.c
++	#include <features.h>
++	#if defined(__UCLIBC__)
++	LIBC=uclibc
++	#elif defined(__dietlibc__)
++	LIBC=dietlibc
++	#else
++	LIBC=gnu
++	#endif
++	EOF
++	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
++	;;
++esac
++
+ # Note: order is significant - the case branches are not exclusive.
+ 
+ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+     *:NetBSD:*:*)
+ 	# NetBSD (nbsd) targets should (where applicable) match one or
+-	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
++	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ 	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+ 	# switched to ELF, *-*-netbsd* would select the old
+ 	# object file format.  This provides both forward
+ 	# compatibility and a consistent mechanism for selecting the
+ 	# object file format.
+ 	#
+ 	# Note: NetBSD doesn't particularly care about the vendor
+ 	# portion of the name.  We always set it to "unknown".
+@@ -175,17 +189,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ 		    # Return netbsd for either.  FIX?
+ 		    os=netbsd
+ 		else
+ 		    os=netbsdelf
+ 		fi
+ 		;;
+ 	    *)
+-	        os=netbsd
++		os=netbsd
+ 		;;
+ 	esac
+ 	# The OS release
+ 	# Debian GNU/NetBSD machines have a different userland, and
+ 	# thus, need a distinct triplet. However, they do not need
+ 	# kernel version information, so it can be replaced with a
+ 	# suitable tag, in the style of linux-gnu.
+ 	case "${UNAME_VERSION}" in
+@@ -196,16 +210,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ 		;;
+ 	esac
+ 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ 	# contains redundant information, the shorter form:
+ 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ 	echo "${machine}-${os}${release}"
+ 	exit ;;
++    *:Bitrig:*:*)
++	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
++	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
++	exit ;;
+     *:OpenBSD:*:*)
+ 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ 	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ 	exit ;;
+     *:ekkoBSD:*:*)
+ 	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ 	exit ;;
+     *:SolidBSD:*:*)
+@@ -218,17 +236,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ 	exit ;;
+     alpha:OSF1:*:*)
+ 	case $UNAME_RELEASE in
+ 	*4.0)
+ 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ 		;;
+ 	*5.*)
+-	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
++		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ 		;;
+ 	esac
+ 	# According to Compaq, /usr/sbin/psrinfo has been available on
+ 	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+ 	# covers most systems running today.  This code pipes the CPU
+ 	# types through head -n 1, so we only detect the type of CPU 0.
+ 	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ 	case "$ALPHA_CPU_TYPE" in
+@@ -264,17 +282,20 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 		UNAME_MACHINE="alphaev79" ;;
+ 	esac
+ 	# A Pn.n version is a patched version.
+ 	# A Vn.n version is a released version.
+ 	# A Tn.n version is a released field test version.
+ 	# A Xn.n version is an unreleased experimental baselevel.
+ 	# 1.2 uses "1.2" for uname -r.
+ 	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+-	exit ;;
++	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
++	exitcode=$?
++	trap '' 0
++	exit $exitcode ;;
+     Alpha\ *:Windows_NT*:*)
+ 	# How do we know it's Interix rather than the generic POSIX subsystem?
+ 	# Should we change UNAME_MACHINE based on the output of uname instead
+ 	# of the specific Alpha model?
+ 	echo alpha-pc-interix
+ 	exit ;;
+     21064:Windows_NT:50:3)
+ 	echo alpha-dec-winnt3.5
+@@ -290,22 +311,22 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 	exit ;;
+     *:OS/390:*:*)
+ 	echo i370-ibm-openedition
+ 	exit ;;
+     *:z/VM:*:*)
+ 	echo s390-ibm-zvmoe
+ 	exit ;;
+     *:OS400:*:*)
+-        echo powerpc-ibm-os400
++	echo powerpc-ibm-os400
+ 	exit ;;
+     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ 	echo arm-acorn-riscix${UNAME_RELEASE}
+ 	exit ;;
+-    arm:riscos:*:*|arm:RISCOS:*:*)
++    arm*:riscos:*:*|arm*:RISCOS:*:*)
+ 	echo arm-unknown-riscos
+ 	exit ;;
+     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ 	echo hppa1.1-hitachi-hiuxmpp
+ 	exit ;;
+     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ 	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ 	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+@@ -328,16 +349,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+ 	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
+     sun4H:SunOS:5.*:*)
+ 	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
+     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ 	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
++    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
++	echo i386-pc-auroraux${UNAME_RELEASE}
++	exit ;;
+     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ 	eval $set_cc_for_build
+ 	SUN_ARCH="i386"
+ 	# If there is a compiler, see if it is configured for 64-bit objects.
+ 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ 	# This test works for both compilers.
+ 	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+@@ -386,33 +410,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
+     # can be virtually everything (everything which is not
+     # "atarist" or "atariste" at least should have a processor
+     # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+     # to the lowercase version "mint" (or "freemint").  Finally
+     # the system name "TOS" denotes a system which is actually not
+     # MiNT.  But MiNT is downward compatible to TOS, so this should
+     # be no problem.
+     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+-        echo m68k-atari-mint${UNAME_RELEASE}
++	echo m68k-atari-mint${UNAME_RELEASE}
+ 	exit ;;
+     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ 	echo m68k-atari-mint${UNAME_RELEASE}
+-        exit ;;
++	exit ;;
+     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+-        echo m68k-atari-mint${UNAME_RELEASE}
++	echo m68k-atari-mint${UNAME_RELEASE}
+ 	exit ;;
+     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+-        echo m68k-milan-mint${UNAME_RELEASE}
+-        exit ;;
++	echo m68k-milan-mint${UNAME_RELEASE}
++	exit ;;
+     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+-        echo m68k-hades-mint${UNAME_RELEASE}
+-        exit ;;
++	echo m68k-hades-mint${UNAME_RELEASE}
++	exit ;;
+     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+-        echo m68k-unknown-mint${UNAME_RELEASE}
+-        exit ;;
++	echo m68k-unknown-mint${UNAME_RELEASE}
++	exit ;;
+     m68k:machten:*:*)
+ 	echo m68k-apple-machten${UNAME_RELEASE}
+ 	exit ;;
+     powerpc:machten:*:*)
+ 	echo powerpc-apple-machten${UNAME_RELEASE}
+ 	exit ;;
+     RISC*:Mach:*:*)
+ 	echo mips-dec-mach_bsd4.3
+@@ -472,31 +496,31 @@ EOF
+ 	exit ;;
+     m88k:*:4*:R4*)
+ 	echo m88k-motorola-sysv4
+ 	exit ;;
+     m88k:*:3*:R3*)
+ 	echo m88k-motorola-sysv3
+ 	exit ;;
+     AViiON:dgux:*:*)
+-        # DG/UX returns AViiON for all architectures
+-        UNAME_PROCESSOR=`/usr/bin/uname -p`
++	# DG/UX returns AViiON for all architectures
++	UNAME_PROCESSOR=`/usr/bin/uname -p`
+ 	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ 	then
+ 	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ 	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+ 	    then
+ 		echo m88k-dg-dgux${UNAME_RELEASE}
+ 	    else
+ 		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ 	    fi
+ 	else
+ 	    echo i586-dg-dgux${UNAME_RELEASE}
+ 	fi
+- 	exit ;;
++	exit ;;
+     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+ 	echo m88k-dolphin-sysv3
+ 	exit ;;
+     M88*:*:R3*:*)
+ 	# Delta 88k system running SVR3
+ 	echo m88k-motorola-sysv3
+ 	exit ;;
+     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+@@ -543,17 +567,17 @@ EOF
+ 			echo rs6000-ibm-aix3.2.5
+ 		fi
+ 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ 		echo rs6000-ibm-aix3.2.4
+ 	else
+ 		echo rs6000-ibm-aix3.2
+ 	fi
+ 	exit ;;
+-    *:AIX:*:[456])
++    *:AIX:*:[4567])
+ 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ 	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ 		IBM_ARCH=rs6000
+ 	else
+ 		IBM_ARCH=powerpc
+ 	fi
+ 	if [ -x /usr/bin/oslevel ] ; then
+ 		IBM_REV=`/usr/bin/oslevel`
+@@ -586,62 +610,62 @@ EOF
+     9000/[34678]??:HP-UX:*:*)
+ 	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ 	case "${UNAME_MACHINE}" in
+ 	    9000/31? )            HP_ARCH=m68000 ;;
+ 	    9000/[34]?? )         HP_ARCH=m68k ;;
+ 	    9000/[678][0-9][0-9])
+ 		if [ -x /usr/bin/getconf ]; then
+ 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+-                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+-                    case "${sc_cpu_version}" in
+-                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+-                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+-                      532)                      # CPU_PA_RISC2_0
+-                        case "${sc_kernel_bits}" in
+-                          32) HP_ARCH="hppa2.0n" ;;
+-                          64) HP_ARCH="hppa2.0w" ;;
++		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
++		    case "${sc_cpu_version}" in
++		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
++		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
++		      532)                      # CPU_PA_RISC2_0
++			case "${sc_kernel_bits}" in
++			  32) HP_ARCH="hppa2.0n" ;;
++			  64) HP_ARCH="hppa2.0w" ;;
+ 			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+-                        esac ;;
+-                    esac
++			esac ;;
++		    esac
+ 		fi
+ 		if [ "${HP_ARCH}" = "" ]; then
+ 		    eval $set_cc_for_build
+-		    sed 's/^              //' << EOF >$dummy.c
++		    sed 's/^		//' << EOF >$dummy.c
+ 
+-              #define _HPUX_SOURCE
+-              #include <stdlib.h>
+-              #include <unistd.h>
++		#define _HPUX_SOURCE
++		#include <stdlib.h>
++		#include <unistd.h>
+ 
+-              int main ()
+-              {
+-              #if defined(_SC_KERNEL_BITS)
+-                  long bits = sysconf(_SC_KERNEL_BITS);
+-              #endif
+-                  long cpu  = sysconf (_SC_CPU_VERSION);
++		int main ()
++		{
++		#if defined(_SC_KERNEL_BITS)
++		    long bits = sysconf(_SC_KERNEL_BITS);
++		#endif
++		    long cpu  = sysconf (_SC_CPU_VERSION);
+ 
+-                  switch (cpu)
+-              	{
+-              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+-              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+-              	case CPU_PA_RISC2_0:
+-              #if defined(_SC_KERNEL_BITS)
+-              	    switch (bits)
+-              		{
+-              		case 64: puts ("hppa2.0w"); break;
+-              		case 32: puts ("hppa2.0n"); break;
+-              		default: puts ("hppa2.0"); break;
+-              		} break;
+-              #else  /* !defined(_SC_KERNEL_BITS) */
+-              	    puts ("hppa2.0"); break;
+-              #endif
+-              	default: puts ("hppa1.0"); break;
+-              	}
+-                  exit (0);
+-              }
++		    switch (cpu)
++			{
++			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
++			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
++			case CPU_PA_RISC2_0:
++		#if defined(_SC_KERNEL_BITS)
++			    switch (bits)
++				{
++				case 64: puts ("hppa2.0w"); break;
++				case 32: puts ("hppa2.0n"); break;
++				default: puts ("hppa2.0"); break;
++				} break;
++		#else  /* !defined(_SC_KERNEL_BITS) */
++			    puts ("hppa2.0"); break;
++		#endif
++			default: puts ("hppa1.0"); break;
++			}
++		    exit (0);
++		}
+ EOF
+ 		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ 		    test -z "$HP_ARCH" && HP_ARCH=hppa
+ 		fi ;;
+ 	esac
+ 	if [ ${HP_ARCH} = "hppa2.0w" ]
+ 	then
+ 	    eval $set_cc_for_build
+@@ -722,32 +746,32 @@ EOF
+ 	    echo ${UNAME_MACHINE}-unknown-osf1
+ 	fi
+ 	exit ;;
+     parisc*:Lites*:*:*)
+ 	echo hppa1.1-hp-lites
+ 	exit ;;
+     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ 	echo c1-convex-bsd
+-        exit ;;
++	exit ;;
+     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ 	if getsysinfo -f scalar_acc
+ 	then echo c32-convex-bsd
+ 	else echo c2-convex-bsd
+ 	fi
+-        exit ;;
++	exit ;;
+     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ 	echo c34-convex-bsd
+-        exit ;;
++	exit ;;
+     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ 	echo c38-convex-bsd
+-        exit ;;
++	exit ;;
+     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ 	echo c4-convex-bsd
+-        exit ;;
++	exit ;;
+     CRAY*Y-MP:*:*:*)
+ 	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ 	exit ;;
+     CRAY*[A-Z]90:*:*:*)
+ 	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ 	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ 	      -e 's/\.[^.]*$/.X/'
+@@ -761,63 +785,68 @@ EOF
+     CRAY*SV1:*:*:*)
+ 	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ 	exit ;;
+     *:UNICOS/mp:*:*)
+ 	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ 	exit ;;
+     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ 	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+-        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+-        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+-        exit ;;
++	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
++	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++	exit ;;
+     5000:UNIX_System_V:4.*:*)
+-        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+-        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+-        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
++	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ 	exit ;;
+     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ 	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ 	exit ;;
+     sparc*:BSD/OS:*:*)
+ 	echo sparc-unknown-bsdi${UNAME_RELEASE}
+ 	exit ;;
+     *:BSD/OS:*:*)
+ 	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ 	exit ;;
+     *:FreeBSD:*:*)
+-	case ${UNAME_MACHINE} in
+-	    pc98)
+-		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++	UNAME_PROCESSOR=`/usr/bin/uname -p`
++	case ${UNAME_PROCESSOR} in
+ 	    amd64)
+ 		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ 	    *)
+-		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ 	esac
+ 	exit ;;
+     i*:CYGWIN*:*)
+ 	echo ${UNAME_MACHINE}-pc-cygwin
+ 	exit ;;
++    *:MINGW64*:*)
++	echo ${UNAME_MACHINE}-pc-mingw64
++	exit ;;
+     *:MINGW*:*)
+ 	echo ${UNAME_MACHINE}-pc-mingw32
+ 	exit ;;
++    i*:MSYS*:*)
++	echo ${UNAME_MACHINE}-pc-msys
++	exit ;;
+     i*:windows32*:*)
+-    	# uname -m includes "-pc" on this system.
+-    	echo ${UNAME_MACHINE}-mingw32
++	# uname -m includes "-pc" on this system.
++	echo ${UNAME_MACHINE}-mingw32
+ 	exit ;;
+     i*:PW*:*)
+ 	echo ${UNAME_MACHINE}-pc-pw32
+ 	exit ;;
+-    *:Interix*:[3456]*)
+-    	case ${UNAME_MACHINE} in
++    *:Interix*:*)
++	case ${UNAME_MACHINE} in
+ 	    x86)
+ 		echo i586-pc-interix${UNAME_RELEASE}
+ 		exit ;;
+-	    EM64T | authenticamd | genuineintel)
++	    authenticamd | genuineintel | EM64T)
+ 		echo x86_64-unknown-interix${UNAME_RELEASE}
+ 		exit ;;
+ 	    IA64)
+ 		echo ia64-unknown-interix${UNAME_RELEASE}
+ 		exit ;;
+ 	esac ;;
+     [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ 	echo i${UNAME_MACHINE}-pc-mks
+@@ -840,55 +869,91 @@ EOF
+     p*:CYGWIN*:*)
+ 	echo powerpcle-unknown-cygwin
+ 	exit ;;
+     prep*:SunOS:5.*:*)
+ 	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ 	exit ;;
+     *:GNU:*:*)
+ 	# the GNU system
+-	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
++	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ 	exit ;;
+     *:GNU/*:*:*)
+ 	# other systems with GNU libc and userland
+-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
++	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ 	exit ;;
+     i*86:Minix:*:*)
+ 	echo ${UNAME_MACHINE}-pc-minix
+ 	exit ;;
++    aarch64:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    aarch64_be:Linux:*:*)
++	UNAME_MACHINE=aarch64_be
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    alpha:Linux:*:*)
++	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
++	  EV5)   UNAME_MACHINE=alphaev5 ;;
++	  EV56)  UNAME_MACHINE=alphaev56 ;;
++	  PCA56) UNAME_MACHINE=alphapca56 ;;
++	  PCA57) UNAME_MACHINE=alphapca56 ;;
++	  EV6)   UNAME_MACHINE=alphaev6 ;;
++	  EV67)  UNAME_MACHINE=alphaev67 ;;
++	  EV68*) UNAME_MACHINE=alphaev68 ;;
++	esac
++	objdump --private-headers /bin/sh | grep -q ld.so.1
++	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    arc:Linux:*:* | arceb:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
+     arm*:Linux:*:*)
+ 	eval $set_cc_for_build
+ 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ 	    | grep -q __ARM_EABI__
+ 	then
+-	    echo ${UNAME_MACHINE}-unknown-linux-gnu
++	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	else
+-	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
++		| grep -q __ARM_PCS_VFP
++	    then
++		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
++	    else
++		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
++	    fi
+ 	fi
+ 	exit ;;
+     avr32*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     cris:Linux:*:*)
+-	echo cris-axis-linux-gnu
++	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ 	exit ;;
+     crisv32:Linux:*:*)
+-	echo crisv32-axis-linux-gnu
++	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ 	exit ;;
+     frv:Linux:*:*)
+-    	echo frv-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    hexagon:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    i*86:Linux:*:*)
++	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ 	exit ;;
+     ia64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     m32r*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     m68*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     mips:Linux:*:* | mips64:Linux:*:*)
+ 	eval $set_cc_for_build
+ 	sed 's/^	//' << EOF >$dummy.c
+ 	#undef CPU
+ 	#undef ${UNAME_MACHINE}
+ 	#undef ${UNAME_MACHINE}el
+ 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+@@ -896,145 +961,87 @@ EOF
+ 	#else
+ 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ 	CPU=${UNAME_MACHINE}
+ 	#else
+ 	CPU=
+ 	#endif
+ 	#endif
+ EOF
+-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+-	    /^CPU/{
+-		s: ::g
+-		p
+-	    }'`"
+-	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
++	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
++	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ 	;;
++    or1k:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
+     or32:Linux:*:*)
+-	echo or32-unknown-linux-gnu
+-	exit ;;
+-    ppc:Linux:*:*)
+-	echo powerpc-unknown-linux-gnu
+-	exit ;;
+-    ppc64:Linux:*:*)
+-	echo powerpc64-unknown-linux-gnu
+-	exit ;;
+-    alpha:Linux:*:*)
+-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+-	  EV5)   UNAME_MACHINE=alphaev5 ;;
+-	  EV56)  UNAME_MACHINE=alphaev56 ;;
+-	  PCA56) UNAME_MACHINE=alphapca56 ;;
+-	  PCA57) UNAME_MACHINE=alphapca56 ;;
+-	  EV6)   UNAME_MACHINE=alphaev6 ;;
+-	  EV67)  UNAME_MACHINE=alphaev67 ;;
+-	  EV68*) UNAME_MACHINE=alphaev68 ;;
+-        esac
+-	objdump --private-headers /bin/sh | grep -q ld.so.1
+-	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     padre:Linux:*:*)
+-	echo sparc-unknown-linux-gnu
++	echo sparc-unknown-linux-${LIBC}
++	exit ;;
++    parisc64:Linux:*:* | hppa64:Linux:*:*)
++	echo hppa64-unknown-linux-${LIBC}
+ 	exit ;;
+     parisc:Linux:*:* | hppa:Linux:*:*)
+ 	# Look for CPU level
+ 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+-	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+-	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+-	  *)    echo hppa-unknown-linux-gnu ;;
++	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
++	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
++	  *)    echo hppa-unknown-linux-${LIBC} ;;
+ 	esac
+ 	exit ;;
+-    parisc64:Linux:*:* | hppa64:Linux:*:*)
+-	echo hppa64-unknown-linux-gnu
++    ppc64:Linux:*:*)
++	echo powerpc64-unknown-linux-${LIBC}
++	exit ;;
++    ppc:Linux:*:*)
++	echo powerpc-unknown-linux-${LIBC}
++	exit ;;
++    ppc64le:Linux:*:*)
++	echo powerpc64le-unknown-linux-${LIBC}
++	exit ;;
++    ppcle:Linux:*:*)
++	echo powerpcle-unknown-linux-${LIBC}
+ 	exit ;;
+     s390:Linux:*:* | s390x:Linux:*:*)
+-	echo ${UNAME_MACHINE}-ibm-linux
++	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ 	exit ;;
+     sh64*:Linux:*:*)
+-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     sh*:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     sparc:Linux:*:* | sparc64:Linux:*:*)
+-	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++	exit ;;
++    tile*:Linux:*:*)
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     vax:Linux:*:*)
+-	echo ${UNAME_MACHINE}-dec-linux-gnu
++	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ 	exit ;;
+     x86_64:Linux:*:*)
+-	echo x86_64-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+     xtensa*:Linux:*:*)
+-    	echo ${UNAME_MACHINE}-unknown-linux-gnu
++	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ 	exit ;;
+-    i*86:Linux:*:*)
+-	# The BFD linker knows what the default object file format is, so
+-	# first see if it will tell us. cd to the root directory to prevent
+-	# problems with other programs or directories called `ld' in the path.
+-	# Set LC_ALL=C to ensure ld outputs messages in English.
+-	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+-			 | sed -ne '/supported targets:/!d
+-				    s/[ 	][ 	]*/ /g
+-				    s/.*supported targets: *//
+-				    s/ .*//
+-				    p'`
+-        case "$ld_supported_targets" in
+-	  elf32-i386)
+-		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+-		;;
+-	esac
+-	# Determine whether the default compiler is a.out or elf
+-	eval $set_cc_for_build
+-	sed 's/^	//' << EOF >$dummy.c
+-	#include <features.h>
+-	#ifdef __ELF__
+-	# ifdef __GLIBC__
+-	#  if __GLIBC__ >= 2
+-	LIBC=gnu
+-	#  else
+-	LIBC=gnulibc1
+-	#  endif
+-	# else
+-	LIBC=gnulibc1
+-	# endif
+-	#else
+-	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+-	LIBC=gnu
+-	#else
+-	LIBC=gnuaout
+-	#endif
+-	#endif
+-	#ifdef __dietlibc__
+-	LIBC=dietlibc
+-	#endif
+-EOF
+-	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+-	    /^LIBC/{
+-		s: ::g
+-		p
+-	    }'`"
+-	test x"${LIBC}" != x && {
+-		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+-		exit
+-	}
+-	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+-	;;
+     i*86:DYNIX/ptx:4*:*)
+ 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ 	# earlier versions are messed up and put the nodename in both
+ 	# sysname and nodename.
+ 	echo i386-sequent-sysv4
+ 	exit ;;
+     i*86:UNIX_SV:4.2MP:2.*)
+-        # Unixware is an offshoot of SVR4, but it has its own version
+-        # number series starting with 2...
+-        # I am not positive that other SVR4 systems won't match this,
++	# Unixware is an offshoot of SVR4, but it has its own version
++	# number series starting with 2...
++	# I am not positive that other SVR4 systems won't match this,
+ 	# I just have to hope.  -- rms.
+-        # Use sysv4.2uw... so that sysv4* matches it.
++	# Use sysv4.2uw... so that sysv4* matches it.
+ 	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ 	exit ;;
+     i*86:OS/2:*:*)
+ 	# If we were able to find `uname', then EMX Unix compatibility
+ 	# is probably installed.
+ 	echo ${UNAME_MACHINE}-pc-os2-emx
+ 	exit ;;
+     i*86:XTS-300:*:STOP)
+@@ -1056,17 +1063,17 @@ EOF
+ 	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ 		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ 	else
+ 		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ 	fi
+ 	exit ;;
+     i*86:*:5:[678]*)
+-    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
++	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+ 	case `/bin/uname -X | grep "^Machine"` in
+ 	    *486*)	     UNAME_MACHINE=i486 ;;
+ 	    *Pentium)	     UNAME_MACHINE=i586 ;;
+ 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ 	esac
+ 	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ 	exit ;;
+     i*86:*:3.2:*)
+@@ -1084,23 +1091,23 @@ EOF
+ 			&& UNAME_MACHINE=i686
+ 		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ 	else
+ 		echo ${UNAME_MACHINE}-pc-sysv32
+ 	fi
+ 	exit ;;
+     pc:*:*:*)
+ 	# Left here for compatibility:
+-        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+-        # the processor, so we play safe by assuming i586.
++	# uname -m prints for DJGPP always 'pc', but it prints nothing about
++	# the processor, so we play safe by assuming i586.
+ 	# Note: whatever this is, it MUST be the same as what config.sub
+ 	# prints for the "djgpp" host, or else GDB configury will decide that
+ 	# this is a cross-build.
+ 	echo i586-pc-msdosdjgpp
+-        exit ;;
++	exit ;;
+     Intel:Mach:3*:*)
+ 	echo i386-pc-mach3
+ 	exit ;;
+     paragon:*:*:*)
+ 	echo i860-intel-osf1
+ 	exit ;;
+     i860:*:4.*:*) # i860-SVR4
+ 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+@@ -1125,18 +1132,18 @@ EOF
+ 	OS_REL=''
+ 	test -r /etc/.relid \
+ 	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ 	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ 	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+-        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+-          && { echo i486-ncr-sysv4; exit; } ;;
++	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
++	  && { echo i486-ncr-sysv4; exit; } ;;
+     NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ 	OS_REL='.3'
+ 	test -r /etc/.relid \
+ 	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ 	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ 	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ 	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ 	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+@@ -1169,20 +1176,20 @@ EOF
+     *:SINIX-*:*:*)
+ 	if uname -p 2>/dev/null >/dev/null ; then
+ 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ 		echo ${UNAME_MACHINE}-sni-sysv4
+ 	else
+ 		echo ns32k-sni-sysv
+ 	fi
+ 	exit ;;
+-    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+-                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+-        echo i586-unisys-sysv4
+-        exit ;;
++    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
++			# says <Richard.M.Bartel@ccMail.Census.GOV>
++	echo i586-unisys-sysv4
++	exit ;;
+     *:UNIX_System_V:4*:FTX*)
+ 	# From Gerald Hewes <hewes@openmarket.com>.
+ 	# How about differentiating between stratus architectures? -djm
+ 	echo hppa1.1-stratus-sysv4
+ 	exit ;;
+     *:*:*:FTX*)
+ 	# From seanf@swdc.stratus.com.
+ 	echo i860-stratus-sysv4
+@@ -1198,33 +1205,36 @@ EOF
+     mc68*:A/UX:*:*)
+ 	echo m68k-apple-aux${UNAME_RELEASE}
+ 	exit ;;
+     news*:NEWS-OS:6*:*)
+ 	echo mips-sony-newsos6
+ 	exit ;;
+     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ 	if [ -d /usr/nec ]; then
+-	        echo mips-nec-sysv${UNAME_RELEASE}
++		echo mips-nec-sysv${UNAME_RELEASE}
+ 	else
+-	        echo mips-unknown-sysv${UNAME_RELEASE}
++		echo mips-unknown-sysv${UNAME_RELEASE}
+ 	fi
+-        exit ;;
++	exit ;;
+     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+ 	echo powerpc-be-beos
+ 	exit ;;
+     BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+ 	echo powerpc-apple-beos
+ 	exit ;;
+     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+ 	echo i586-pc-beos
+ 	exit ;;
+     BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+ 	echo i586-pc-haiku
+ 	exit ;;
++    x86_64:Haiku:*:*)
++	echo x86_64-unknown-haiku
++	exit ;;
+     SX-4:SUPER-UX:*:*)
+ 	echo sx4-nec-superux${UNAME_RELEASE}
+ 	exit ;;
+     SX-5:SUPER-UX:*:*)
+ 	echo sx5-nec-superux${UNAME_RELEASE}
+ 	exit ;;
+     SX-6:SUPER-UX:*:*)
+ 	echo sx6-nec-superux${UNAME_RELEASE}
+@@ -1241,37 +1251,58 @@ EOF
+     Power*:Rhapsody:*:*)
+ 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ 	exit ;;
+     *:Rhapsody:*:*)
+ 	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ 	exit ;;
+     *:Darwin:*:*)
+ 	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+-	case $UNAME_PROCESSOR in
+-	    i386) eval $set_cc_for_build
+-	          if $CC_FOR_BUILD -E -dM -x c /dev/null | grep __LP64__>/dev/null 2>&1 ; then
+-	            UNAME_PROCESSOR=x86_64
+-	          fi ;;
+-	    unknown) UNAME_PROCESSOR=powerpc ;;
+-	esac
++	eval $set_cc_for_build
++	if test "$UNAME_PROCESSOR" = unknown ; then
++	    UNAME_PROCESSOR=powerpc
++	fi
++	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
++	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
++		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++		    grep IS_64BIT_ARCH >/dev/null
++		then
++		    case $UNAME_PROCESSOR in
++			i386) UNAME_PROCESSOR=x86_64 ;;
++			powerpc) UNAME_PROCESSOR=powerpc64 ;;
++		    esac
++		fi
++	    fi
++	elif test "$UNAME_PROCESSOR" = i386 ; then
++	    # Avoid executing cc on OS X 10.9, as it ships with a stub
++	    # that puts up a graphical alert prompting to install
++	    # developer tools.  Any system running Mac OS X 10.7 or
++	    # later (Darwin 11 and later) is required to have a 64-bit
++	    # processor. This is not true of the ARM version of Darwin
++	    # that Apple uses in portable devices.
++	    UNAME_PROCESSOR=x86_64
++	fi
+ 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ 	exit ;;
+     *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ 	UNAME_PROCESSOR=`uname -p`
+ 	if test "$UNAME_PROCESSOR" = "x86"; then
+ 		UNAME_PROCESSOR=i386
+ 		UNAME_MACHINE=pc
+ 	fi
+ 	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ 	exit ;;
+     *:QNX:*:4*)
+ 	echo i386-pc-qnx
+ 	exit ;;
+-    NSE-?:NONSTOP_KERNEL:*:*)
++    NEO-?:NONSTOP_KERNEL:*:*)
++	echo neo-tandem-nsk${UNAME_RELEASE}
++	exit ;;
++    NSE-*:NONSTOP_KERNEL:*:*)
+ 	echo nse-tandem-nsk${UNAME_RELEASE}
+ 	exit ;;
+     NSR-?:NONSTOP_KERNEL:*:*)
+ 	echo nsr-tandem-nsk${UNAME_RELEASE}
+ 	exit ;;
+     *:NonStop-UX:*:*)
+ 	echo mips-compaq-nonstopux
+ 	exit ;;
+@@ -1306,23 +1337,23 @@ EOF
+ 	exit ;;
+     *:TOPS-20:*:*)
+ 	echo pdp10-unknown-tops20
+ 	exit ;;
+     *:ITS:*:*)
+ 	echo pdp10-unknown-its
+ 	exit ;;
+     SEI:*:*:SEIUX)
+-        echo mips-sei-seiux${UNAME_RELEASE}
++	echo mips-sei-seiux${UNAME_RELEASE}
+ 	exit ;;
+     *:DragonFly:*:*)
+ 	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ 	exit ;;
+     *:*VMS:*:*)
+-    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
++	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ 	case "${UNAME_MACHINE}" in
+ 	    A*) echo alpha-dec-vms ; exit ;;
+ 	    I*) echo ia64-dec-vms ; exit ;;
+ 	    V*) echo vax-dec-vms ; exit ;;
+ 	esac ;;
+     *:XENIX:*:SysV)
+ 	echo i386-pc-xenix
+ 	exit ;;
+@@ -1330,169 +1361,21 @@ EOF
+ 	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ 	exit ;;
+     i*86:rdos:*:*)
+ 	echo ${UNAME_MACHINE}-pc-rdos
+ 	exit ;;
+     i*86:AROS:*:*)
+ 	echo ${UNAME_MACHINE}-pc-aros
+ 	exit ;;
++    x86_64:VMkernel:*:*)
++	echo ${UNAME_MACHINE}-unknown-esx
++	exit ;;
+ esac
+ 
+-#echo '(No uname command or uname output not recognized.)' 1>&2
+-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+-
+-eval $set_cc_for_build
+-cat >$dummy.c <<EOF
+-#ifdef _SEQUENT_
+-# include <sys/types.h>
+-# include <sys/utsname.h>
+-#endif
+-main ()
+-{
+-#if defined (sony)
+-#if defined (MIPSEB)
+-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+-     I don't know....  */
+-  printf ("mips-sony-bsd\n"); exit (0);
+-#else
+-#include <sys/param.h>
+-  printf ("m68k-sony-newsos%s\n",
+-#ifdef NEWSOS4
+-          "4"
+-#else
+-	  ""
+-#endif
+-         ); exit (0);
+-#endif
+-#endif
+-
+-#if defined (__arm) && defined (__acorn) && defined (__unix)
+-  printf ("arm-acorn-riscix\n"); exit (0);
+-#endif
+-
+-#if defined (hp300) && !defined (hpux)
+-  printf ("m68k-hp-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (NeXT)
+-#if !defined (__ARCHITECTURE__)
+-#define __ARCHITECTURE__ "m68k"
+-#endif
+-  int version;
+-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+-  if (version < 4)
+-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+-  else
+-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+-  exit (0);
+-#endif
+-
+-#if defined (MULTIMAX) || defined (n16)
+-#if defined (UMAXV)
+-  printf ("ns32k-encore-sysv\n"); exit (0);
+-#else
+-#if defined (CMU)
+-  printf ("ns32k-encore-mach\n"); exit (0);
+-#else
+-  printf ("ns32k-encore-bsd\n"); exit (0);
+-#endif
+-#endif
+-#endif
+-
+-#if defined (__386BSD__)
+-  printf ("i386-pc-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (sequent)
+-#if defined (i386)
+-  printf ("i386-sequent-dynix\n"); exit (0);
+-#endif
+-#if defined (ns32000)
+-  printf ("ns32k-sequent-dynix\n"); exit (0);
+-#endif
+-#endif
+-
+-#if defined (_SEQUENT_)
+-    struct utsname un;
+-
+-    uname(&un);
+-
+-    if (strncmp(un.version, "V2", 2) == 0) {
+-	printf ("i386-sequent-ptx2\n"); exit (0);
+-    }
+-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+-	printf ("i386-sequent-ptx1\n"); exit (0);
+-    }
+-    printf ("i386-sequent-ptx\n"); exit (0);
+-
+-#endif
+-
+-#if defined (vax)
+-# if !defined (ultrix)
+-#  include <sys/param.h>
+-#  if defined (BSD)
+-#   if BSD == 43
+-      printf ("vax-dec-bsd4.3\n"); exit (0);
+-#   else
+-#    if BSD == 199006
+-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+-#    else
+-      printf ("vax-dec-bsd\n"); exit (0);
+-#    endif
+-#   endif
+-#  else
+-    printf ("vax-dec-bsd\n"); exit (0);
+-#  endif
+-# else
+-    printf ("vax-dec-ultrix\n"); exit (0);
+-# endif
+-#endif
+-
+-#if defined (alliant) && defined (i860)
+-  printf ("i860-alliant-bsd\n"); exit (0);
+-#endif
+-
+-  exit (1);
+-}
+-EOF
+-
+-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+-	{ echo "$SYSTEM_NAME"; exit; }
+-
+-# Apollos put the system type in the environment.
+-
+-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+-
+-# Convex versions that predate uname can use getsysinfo(1)
+-
+-if [ -x /usr/convex/getsysinfo ]
+-then
+-    case `getsysinfo -f cpu_type` in
+-    c1*)
+-	echo c1-convex-bsd
+-	exit ;;
+-    c2*)
+-	if getsysinfo -f scalar_acc
+-	then echo c32-convex-bsd
+-	else echo c2-convex-bsd
+-	fi
+-	exit ;;
+-    c34*)
+-	echo c34-convex-bsd
+-	exit ;;
+-    c38*)
+-	echo c38-convex-bsd
+-	exit ;;
+-    c4*)
+-	echo c4-convex-bsd
+-	exit ;;
+-    esac
+-fi
+-
+ cat >&2 <<EOF
+ $0: unable to guess system type
+ 
+ This script, last modified $timestamp, has failed to recognize
+ the operating system you are using. It is advised that you
+ download the most up to date version of the config scripts from
+ 
+   http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+diff --git a/js/src/build/autoconf/config.sub b/js/src/build/autoconf/config.sub
+--- a/js/src/build/autoconf/config.sub
++++ b/js/src/build/autoconf/config.sub
+@@ -1,43 +1,36 @@
+ #! /bin/sh
+ # Configuration validation subroutine script.
+-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-#   Free Software Foundation, Inc.
++#   Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+-timestamp='2011-01-03'
++timestamp='2014-01-01'
+ 
+-# This file is (in principle) common to ALL GNU software.
+-# The presence of a machine in this file suggests that SOME GNU software
+-# can handle that machine.  It does not imply ALL GNU software can.
+-#
+-# This file is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# This file is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-# GNU General Public License for more details.
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++# General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
++# the same distribution terms that you use for the rest of that
++# program.  This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ 
+ 
+-# Please send patches to <config-patches@gnu.org>.  Submit a context
+-# diff and a properly formatted GNU ChangeLog entry.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+ # If it is invalid, we print an error message on stderr and exit with code 1.
+ # Otherwise, we print the canonical config type on stdout and succeed.
+ 
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+@@ -70,18 +63,17 @@ Operation modes:
+   -t, --time-stamp   print date of last modification, then exit
+   -v, --version      print version number, then exit
+ 
+ Report bugs and patches to <config-patches@gnu.org>."
+ 
+ version="\
+ GNU config.sub ($timestamp)
+ 
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+ 
+ This is free software; see the source for copying conditions.  There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+ 
+ help="
+ Try \`$me --help' for more information."
+ 
+ # Parse command line
+@@ -118,23 +110,28 @@ case $# in
+  *) echo "$me: too many arguments$help" >&2
+     exit 1;;
+ esac
+ 
+ # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+ # Here we must recognize all the valid KERNEL-OS combinations.
+ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ case $maybe_os in
+-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+-  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
++  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
++  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
++  knetbsd*-gnu* | netbsd*-gnu* | \
+   kopensolaris*-gnu* | \
+-  storm-chaos* | os2-emx* | rtmk-nova* | wince-winmo*)
++  storm-chaos* | os2-emx* | rtmk-nova*)
+     os=-$maybe_os
+     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+     ;;
++  android-linux)
++    os=-linux-android
++    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
++    ;;
+   *)
+     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+     if [ $basic_machine != $1 ]
+     then os=`echo $1 | sed 's/.*-/-/'`
+     else os=; fi
+     ;;
+ esac
+ 
+@@ -147,41 +144,41 @@ case $os in
+ 		# Prevent following clause from handling this invalid input.
+ 		;;
+ 	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ 	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ 	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ 	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ 	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ 	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+-	-apple | -axis | -knuth | -cray | -microblaze)
++	-apple | -axis | -knuth | -cray | -microblaze*)
+ 		os=
+ 		basic_machine=$1
+ 		;;
+-        -bluegene*)
+-	        os=-cnk
++	-bluegene*)
++		os=-cnk
+ 		;;
+ 	-sim | -cisco | -oki | -wec | -winbond)
+ 		os=
+ 		basic_machine=$1
+ 		;;
+ 	-scout)
+ 		;;
+ 	-wrs)
+ 		os=-vxworks
+ 		basic_machine=$1
+ 		;;
+ 	-chorusos*)
+ 		os=-chorusos
+ 		basic_machine=$1
+ 		;;
+- 	-chorusrdb)
+- 		os=-chorusrdb
++	-chorusrdb)
++		os=-chorusrdb
+ 		basic_machine=$1
+- 		;;
++		;;
+ 	-hiux*)
+ 		os=-hiuxwe2
+ 		;;
+ 	-sco6)
+ 		os=-sco5v6
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ 		;;
+ 	-sco5)
+@@ -216,16 +213,22 @@ case $os in
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ 		;;
+ 	-clix*)
+ 		basic_machine=clipper-intergraph
+ 		;;
+ 	-isc*)
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ 		;;
++	-lynx*178)
++		os=-lynxos178
++		;;
++	-lynx*5)
++		os=-lynxos5
++		;;
+ 	-lynx*)
+ 		os=-lynxos
+ 		;;
+ 	-ptx*)
+ 		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ 		;;
+ 	-windowsnt*)
+ 		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+@@ -240,30 +243,38 @@ case $os in
+ esac
+ 
+ # Decode aliases for certain CPU-COMPANY combinations.
+ case $basic_machine in
+ 	# Recognize the basic CPU types without company name.
+ 	# Some are omitted here because they have special meanings below.
+ 	1750a | 580 \
+ 	| a29k \
++	| aarch64 | aarch64_be \
+ 	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ 	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ 	| am33_2.0 \
+-	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
++	| arc | arceb \
++	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
++	| avr | avr32 \
++	| be32 | be64 \
+ 	| bfin \
+-	| c4x | clipper \
++	| c4x | c8051 | clipper \
+ 	| d10v | d30v | dlx | dsp16xx \
++	| epiphany \
+ 	| fido | fr30 | frv \
+ 	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
++	| hexagon \
+ 	| i370 | i860 | i960 | ia64 \
+ 	| ip2k | iq2000 \
++	| k1om \
++	| le32 | le64 \
+ 	| lm32 \
+ 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+-	| maxq | mb | microblaze | mcore | mep | metag \
++	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ 	| mips | mipsbe | mipseb | mipsel | mipsle \
+ 	| mips16 \
+ 	| mips64 | mips64el \
+ 	| mips64octeon | mips64octeonel \
+ 	| mips64orion | mips64orionel \
+ 	| mips64r5900 | mips64r5900el \
+ 	| mips64vr | mips64vrel \
+ 	| mips64vr4100 | mips64vr4100el \
+@@ -271,84 +282,118 @@ case $basic_machine in
+ 	| mips64vr5000 | mips64vr5000el \
+ 	| mips64vr5900 | mips64vr5900el \
+ 	| mipsisa32 | mipsisa32el \
+ 	| mipsisa32r2 | mipsisa32r2el \
+ 	| mipsisa64 | mipsisa64el \
+ 	| mipsisa64r2 | mipsisa64r2el \
+ 	| mipsisa64sb1 | mipsisa64sb1el \
+ 	| mipsisa64sr71k | mipsisa64sr71kel \
++	| mipsr5900 | mipsr5900el \
+ 	| mipstx39 | mipstx39el \
+ 	| mn10200 | mn10300 \
+ 	| moxie \
+ 	| mt \
+ 	| msp430 \
+-	| nios | nios2 \
++	| nds32 | nds32le | nds32be \
++	| nios | nios2 | nios2eb | nios2el \
+ 	| ns16k | ns32k \
+-	| or32 \
++	| open8 \
++	| or1k | or32 \
+ 	| pdp10 | pdp11 | pj | pjl \
+-	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
++	| powerpc | powerpc64 | powerpc64le | powerpcle \
+ 	| pyramid \
++	| rl78 | rx \
+ 	| score \
+ 	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ 	| sh64 | sh64le \
+ 	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ 	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+-	| spu | strongarm \
+-	| tahoe | thumb | tic4x | tic80 | tron \
+-	| v850 | v850e \
++	| spu \
++	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
++	| ubicom32 \
++	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ 	| we32k \
+-	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
++	| x86 | xc16x | xstormy16 | xtensa \
+ 	| z8k | z80)
+ 		basic_machine=$basic_machine-unknown
+ 		;;
+-	m6811 | m68hc11 | m6812 | m68hc12)
+-		# Motorola 68HC11/12.
++	c54x)
++		basic_machine=tic54x-unknown
++		;;
++	c55x)
++		basic_machine=tic55x-unknown
++		;;
++	c6x)
++		basic_machine=tic6x-unknown
++		;;
++	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ 		basic_machine=$basic_machine-unknown
+ 		os=-none
+ 		;;
+ 	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ 		;;
+ 	ms1)
+ 		basic_machine=mt-unknown
+ 		;;
+ 
++	strongarm | thumb | xscale)
++		basic_machine=arm-unknown
++		;;
++	xgate)
++		basic_machine=$basic_machine-unknown
++		os=-none
++		;;
++	xscaleeb)
++		basic_machine=armeb-unknown
++		;;
++
++	xscaleel)
++		basic_machine=armel-unknown
++		;;
++
+ 	# We use `pc' rather than `unknown'
+ 	# because (1) that's what they normally are, and
+ 	# (2) the word "unknown" tends to confuse beginning users.
+ 	i*86 | x86_64)
+ 	  basic_machine=$basic_machine-pc
+ 	  ;;
+ 	# Object if more than one company name word.
+ 	*-*-*)
+ 		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ 		exit 1
+ 		;;
+ 	# Recognize the basic CPU types with company name.
+ 	580-* \
+ 	| a29k-* \
++	| aarch64-* | aarch64_be-* \
+ 	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ 	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
++	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ 	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+ 	| avr-* | avr32-* \
++	| be32-* | be64-* \
+ 	| bfin-* | bs2000-* \
+-	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+-	| clipper-* | craynv-* | cydra-* \
++	| c[123]* | c30-* | [cjt]90-* | c4x-* \
++	| c8051-* | clipper-* | craynv-* | cydra-* \
+ 	| d10v-* | d30v-* | dlx-* \
+ 	| elxsi-* \
+ 	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ 	| h8300-* | h8500-* \
+ 	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
++	| hexagon-* \
+ 	| i*86-* | i860-* | i960-* | ia64-* \
+ 	| ip2k-* | iq2000-* \
++	| k1om-* \
++	| le32-* | le64-* \
+ 	| lm32-* \
+ 	| m32c-* | m32r-* | m32rle-* \
+ 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
++	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
++	| microblaze-* | microblazeel-* \
+ 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ 	| mips16-* \
+ 	| mips64-* | mips64el-* \
+ 	| mips64octeon-* | mips64octeonel-* \
+ 	| mips64orion-* | mips64orionel-* \
+ 	| mips64r5900-* | mips64r5900el-* \
+ 	| mips64vr-* | mips64vrel-* \
+ 	| mips64vr4100-* | mips64vr4100el-* \
+@@ -356,38 +401,44 @@ case $basic_machine in
+ 	| mips64vr5000-* | mips64vr5000el-* \
+ 	| mips64vr5900-* | mips64vr5900el-* \
+ 	| mipsisa32-* | mipsisa32el-* \
+ 	| mipsisa32r2-* | mipsisa32r2el-* \
+ 	| mipsisa64-* | mipsisa64el-* \
+ 	| mipsisa64r2-* | mipsisa64r2el-* \
+ 	| mipsisa64sb1-* | mipsisa64sb1el-* \
+ 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
++	| mipsr5900-* | mipsr5900el-* \
+ 	| mipstx39-* | mipstx39el-* \
+ 	| mmix-* \
+ 	| mt-* \
+ 	| msp430-* \
+-	| nios-* | nios2-* \
++	| nds32-* | nds32le-* | nds32be-* \
++	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+ 	| none-* | np1-* | ns16k-* | ns32k-* \
++	| open8-* \
+ 	| orion-* \
+ 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
++	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ 	| pyramid-* \
+-	| romp-* | rs6000-* \
++	| rl78-* | romp-* | rs6000-* | rx-* \
+ 	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ 	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ 	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ 	| sparclite-* \
+-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+-	| tahoe-* | thumb-* \
+-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
++	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
++	| tahoe-* \
++	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
++	| tile*-* \
+ 	| tron-* \
+-	| v850-* | v850e-* | vax-* \
++	| ubicom32-* \
++	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
++	| vax-* \
+ 	| we32k-* \
+-	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
++	| x86-* | x86_64-* | xc16x-* | xps100-* \
+ 	| xstormy16-* | xtensa*-* \
+ 	| ymp-* \
+ 	| z8k-* | z80-*)
+ 		;;
+ 	# Recognize the basic CPU types without company name, with glob match.
+ 	xtensa*)
+ 		basic_machine=$basic_machine-unknown
+ 		;;
+@@ -402,17 +453,17 @@ case $basic_machine in
+ 		;;
+ 	3b*)
+ 		basic_machine=we32k-att
+ 		;;
+ 	a29khif)
+ 		basic_machine=a29k-amd
+ 		os=-udi
+ 		;;
+-    	abacus)
++	abacus)
+ 		basic_machine=abacus-unknown
+ 		;;
+ 	adobe68k)
+ 		basic_machine=m68010-adobe
+ 		os=-scout
+ 		;;
+ 	alliant | fx80)
+ 		basic_machine=fx80-alliant
+@@ -472,21 +523,30 @@ case $basic_machine in
+ 	blackfin-*)
+ 		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		os=-linux
+ 		;;
+ 	bluegene*)
+ 		basic_machine=powerpc-ibm
+ 		os=-cnk
+ 		;;
++	c54x-*)
++		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
++	c55x-*)
++		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
++	c6x-*)
++		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
+ 	c90)
+ 		basic_machine=c90-cray
+ 		os=-unicos
+ 		;;
+-        cegcc)
++	cegcc)
+ 		basic_machine=arm-unknown
+ 		os=-cegcc
+ 		;;
+ 	convex-c1)
+ 		basic_machine=c1-convex
+ 		os=-bsd
+ 		;;
+ 	convex-c2)
+@@ -508,17 +568,17 @@ case $basic_machine in
+ 	cray | j90)
+ 		basic_machine=j90-cray
+ 		os=-unicos
+ 		;;
+ 	craynv)
+ 		basic_machine=craynv-cray
+ 		os=-unicosmp
+ 		;;
+-	cr16)
++	cr16 | cr16-*)
+ 		basic_machine=cr16-unknown
+ 		os=-elf
+ 		;;
+ 	crds | unos)
+ 		basic_machine=m68k-crds
+ 		;;
+ 	crisv32 | crisv32-* | etraxfs*)
+ 		basic_machine=crisv32-axis
+@@ -666,17 +726,16 @@ case $basic_machine in
+ 		;;
+ 	hppro)
+ 		basic_machine=hppa1.1-hp
+ 		os=-proelf
+ 		;;
+ 	i370-ibm* | ibm*)
+ 		basic_machine=i370-ibm
+ 		;;
+-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+ 	i*86v32)
+ 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ 		os=-sysv32
+ 		;;
+ 	i*86v4*)
+ 		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ 		os=-sysv4
+ 		;;
+@@ -724,21 +783,25 @@ case $basic_machine in
+ 	magnum | m3230)
+ 		basic_machine=mips-mips
+ 		os=-sysv
+ 		;;
+ 	merlin)
+ 		basic_machine=ns32k-utek
+ 		os=-sysv
+ 		;;
+-        microblaze)
++	microblaze*)
+ 		basic_machine=microblaze-xilinx
+ 		;;
++	mingw64)
++		basic_machine=x86_64-pc
++		os=-mingw64
++		;;
+ 	mingw32)
+-		basic_machine=i386-pc
++		basic_machine=i686-pc
+ 		os=-mingw32
+ 		;;
+ 	mingw32ce)
+ 		basic_machine=arm-unknown
+ 		os=-mingw32ce
+ 		;;
+ 	miniframe)
+ 		basic_machine=m68000-convergent
+@@ -763,20 +826,28 @@ case $basic_machine in
+ 		;;
+ 	msdos)
+ 		basic_machine=i386-pc
+ 		os=-msdos
+ 		;;
+ 	ms1-*)
+ 		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ 		;;
++	msys)
++		basic_machine=i686-pc
++		os=-msys
++		;;
+ 	mvs)
+ 		basic_machine=i370-ibm
+ 		os=-mvs
+ 		;;
++	nacl)
++		basic_machine=le32-unknown
++		os=-nacl
++		;;
+ 	ncr3000)
+ 		basic_machine=i486-ncr
+ 		os=-sysv4
+ 		;;
+ 	netbsd386)
+ 		basic_machine=i386-unknown
+ 		os=-netbsd
+ 		;;
+@@ -831,16 +902,22 @@ case $basic_machine in
+ 		;;
+ 	nonstopux)
+ 		basic_machine=mips-compaq
+ 		os=-nonstopux
+ 		;;
+ 	np1)
+ 		basic_machine=np1-gould
+ 		;;
++	neo-tandem)
++		basic_machine=neo-tandem
++		;;
++	nse-tandem)
++		basic_machine=nse-tandem
++		;;
+ 	nsr-tandem)
+ 		basic_machine=nsr-tandem
+ 		;;
+ 	op50n-* | op60c-*)
+ 		basic_machine=hppa1.1-oki
+ 		os=-proelf
+ 		;;
+ 	openrisc | openrisc-*)
+@@ -913,19 +990,20 @@ case $basic_machine in
+ 	pentium4-*)
+ 		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		;;
+ 	pn)
+ 		basic_machine=pn-gould
+ 		;;
+ 	power)	basic_machine=power-ibm
+ 		;;
+-	ppc)	basic_machine=powerpc-unknown
++	ppc | ppcbe)	basic_machine=powerpc-unknown
+ 		;;
+-	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
++	ppc-* | ppcbe-*)
++		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		;;
+ 	ppcle | powerpclittle | ppc-le | powerpc-little)
+ 		basic_machine=powerpcle-unknown
+ 		;;
+ 	ppcle-* | powerpclittle-*)
+ 		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ 		;;
+ 	ppc64)	basic_machine=powerpc64-unknown
+@@ -940,17 +1018,21 @@ case $basic_machine in
+ 		;;
+ 	ps2)
+ 		basic_machine=i386-ibm
+ 		;;
+ 	pw32)
+ 		basic_machine=i586-unknown
+ 		os=-pw32
+ 		;;
+-	rdos)
++	rdos | rdos64)
++		basic_machine=x86_64-pc
++		os=-rdos
++		;;
++	rdos32)
+ 		basic_machine=i386-pc
+ 		os=-rdos
+ 		;;
+ 	rom68k)
+ 		basic_machine=m68k-rom68k
+ 		os=-coff
+ 		;;
+ 	rm[46]00)
+@@ -1009,16 +1091,19 @@ case $basic_machine in
+ 		;;
+ 	st2000)
+ 		basic_machine=m68k-tandem
+ 		;;
+ 	stratus)
+ 		basic_machine=i860-stratus
+ 		os=-sysv4
+ 		;;
++	strongarm-* | thumb-*)
++		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
++		;;
+ 	sun2)
+ 		basic_machine=m68000-sun
+ 		;;
+ 	sun2os3)
+ 		basic_machine=m68000-sun
+ 		os=-sunos3
+ 		;;
+ 	sun2os4)
+@@ -1065,30 +1150,18 @@ case $basic_machine in
+ 	t3e)
+ 		basic_machine=alphaev5-cray
+ 		os=-unicos
+ 		;;
+ 	t90)
+ 		basic_machine=t90-cray
+ 		os=-unicos
+ 		;;
+-	tic54x | c54x*)
+-		basic_machine=tic54x-unknown
+-		os=-coff
+-		;;
+-	tic55x | c55x*)
+-		basic_machine=tic55x-unknown
+-		os=-coff
+-		;;
+-	tic6x | c6x*)
+-		basic_machine=tic6x-unknown
+-		os=-coff
+-		;;
+ 	tile*)
+-		basic_machine=tile-unknown
++		basic_machine=$basic_machine-unknown
+ 		os=-linux-gnu
+ 		;;
+ 	tx39)
+ 		basic_machine=mipstx39-unknown
+ 		;;
+ 	tx39el)
+ 		basic_machine=mipstx39el-unknown
+ 		;;
+@@ -1148,16 +1221,19 @@ case $basic_machine in
+ 		;;
+ 	xbox)
+ 		basic_machine=i686-pc
+ 		os=-mingw32
+ 		;;
+ 	xps | xps100)
+ 		basic_machine=xps100-honeywell
+ 		;;
++	xscale-* | xscalee[bl]-*)
++		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
++		;;
+ 	ymp)
+ 		basic_machine=ymp-cray
+ 		os=-unicos
+ 		;;
+ 	z8k-*-coff)
+ 		basic_machine=z8k-unknown
+ 		os=-sim
+ 		;;
+@@ -1245,19 +1321,22 @@ case $basic_machine in
+ 		;;
+ esac
+ 
+ # Decode manufacturer-specific aliases for certain operating systems.
+ 
+ if [ x"$os" != x"" ]
+ then
+ case $os in
+-        # First match some system type aliases
+-        # that might get confused with valid system types.
++	# First match some system type aliases
++	# that might get confused with valid system types.
+ 	# -solaris* is a basic system type, with this one exception.
++	-auroraux)
++		os=-auroraux
++		;;
+ 	-solaris1 | -solaris1.*)
+ 		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ 		;;
+ 	-solaris)
+ 		os=-solaris2
+ 		;;
+ 	-svr4*)
+ 		os=-sysv4
+@@ -1269,39 +1348,40 @@ case $os in
+ 		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ 		;;
+ 	# First accept the basic system types.
+ 	# The portable systems comes first.
+ 	# Each alternative MUST END IN A *, to match a version number.
+ 	# -sysv* is not here because it comes later, after sysvr4.
+ 	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ 	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+-	      | -kopensolaris* \
++	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
++	      | -sym* | -kopensolaris* | -plan9* \
+ 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ 	      | -aos* | -aros* \
+ 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+-	      | -openbsd* | -solidbsd* \
++	      | -bitrig* | -openbsd* | -solidbsd* \
+ 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ 	      | -chorusos* | -chorusrdb* | -cegcc* \
+-	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+-	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
++	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
++	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
++	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ 	      | -uxpv* | -beos* | -mpeix* | -udk* \
+ 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -winmo*)
++	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ 	# Remember, each alternative MUST END IN *, to match a version number.
+ 		;;
+ 	-qnx*)
+ 		case $basic_machine in
+ 		    x86-* | i*86-*)
+ 			;;
+ 		    *)
+ 			os=-nto$os
+@@ -1330,22 +1410,19 @@ case $os in
+ 		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ 		;;
+ 	-sunos6*)
+ 		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ 		;;
+ 	-opened*)
+ 		os=-openedition
+ 		;;
+-        -os400*)
++	-os400*)
+ 		os=-os400
+ 		;;
+-	-wince-winmo*)
+-		os=-wince-winmo
+-		;;
+ 	-wince*)
+ 		os=-wince
+ 		;;
+ 	-osfrose*)
+ 		os=-osfrose
+ 		;;
+ 	-osf*)
+ 		os=-osf
+@@ -1382,17 +1459,17 @@ case $os in
+ 		;;
+ 	# Preserve the version number of sinix5.
+ 	-sinix5.*)
+ 		os=`echo $os | sed -e 's|sinix|sysv|'`
+ 		;;
+ 	-sinix*)
+ 		os=-sysv4
+ 		;;
+-        -tpf*)
++	-tpf*)
+ 		os=-tpf
+ 		;;
+ 	-triton*)
+ 		os=-sysv3
+ 		;;
+ 	-oss*)
+ 		os=-sysv3
+ 		;;
+@@ -1418,28 +1495,24 @@ case $os in
+ 		os=-xenix
+ 		;;
+ 	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ 		os=-mint
+ 		;;
+ 	-aros*)
+ 		os=-aros
+ 		;;
+-	-kaos*)
+-		os=-kaos
+-		;;
+ 	-zvmoe)
+ 		os=-zvmoe
+ 		;;
+ 	-dicos*)
+ 		os=-dicos
+ 		;;
+-        -android*)
+-	        os=-android
+-                ;;
++	-nacl*)
++		;;
+ 	-none)
+ 		;;
+ 	*)
+ 		# Get rid of the `-' at the beginning of $os.
+ 		os=`echo $os | sed 's/[^-]*-//'`
+ 		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ 		exit 1
+ 		;;
+@@ -1452,33 +1525,48 @@ else
+ 
+ # Note that if you're going to try to match "-MANUFACTURER" here (say,
+ # "-sun"), then you have to tell the case statement up towards the top
+ # that MANUFACTURER isn't an operating system.  Otherwise, code above
+ # will signal an error saying that MANUFACTURER isn't an operating
+ # system, and we'll never get to this point.
+ 
+ case $basic_machine in
+-        score-*)
++	score-*)
+ 		os=-elf
+ 		;;
+-        spu-*)
++	spu-*)
+ 		os=-elf
+ 		;;
+ 	*-acorn)
+ 		os=-riscix1.2
+ 		;;
+ 	arm*-rebel)
+ 		os=-linux
+ 		;;
+ 	arm*-semi)
+ 		os=-aout
+ 		;;
+-        c4x-* | tic4x-*)
+-        	os=-coff
++	c4x-* | tic4x-*)
++		os=-coff
++		;;
++	c8051-*)
++		os=-elf
++		;;
++	hexagon-*)
++		os=-elf
++		;;
++	tic54x-*)
++		os=-coff
++		;;
++	tic55x-*)
++		os=-coff
++		;;
++	tic6x-*)
++		os=-coff
+ 		;;
+ 	# This must come before the *-dec entry.
+ 	pdp10-*)
+ 		os=-tops20
+ 		;;
+ 	pdp11-*)
+ 		os=-none
+ 		;;
+@@ -1488,32 +1576,32 @@ case $basic_machine in
+ 	m68*-apollo)
+ 		os=-domain
+ 		;;
+ 	i386-sun)
+ 		os=-sunos4.0.2
+ 		;;
+ 	m68000-sun)
+ 		os=-sunos3
+-		# This also exists in the configure program, but was not the
+-		# default.
+-		# os=-sunos4
+ 		;;
+ 	m68*-cisco)
+ 		os=-aout
+ 		;;
+-        mep-*)
++	mep-*)
+ 		os=-elf
+ 		;;
+ 	mips*-cisco)
+ 		os=-elf
+ 		;;
+ 	mips*-*)
+ 		os=-elf
+ 		;;
++	or1k-*)
++		os=-elf
++		;;
+ 	or32-*)
+ 		os=-coff
+ 		;;
+ 	*-tti)	# must be before sparc entry or we get the wrong os.
+ 		os=-sysv3
+ 		;;
+ 	sparc-* | *-sun)
+ 		os=-sunos4.1.1
+@@ -1522,17 +1610,17 @@ case $basic_machine in
+ 		os=-beos
+ 		;;
+ 	*-haiku)
+ 		os=-haiku
+ 		;;
+ 	*-ibm)
+ 		os=-aix
+ 		;;
+-    	*-knuth)
++	*-knuth)
+ 		os=-mmixware
+ 		;;
+ 	*-wec)
+ 		os=-proelf
+ 		;;
+ 	*-winbond)
+ 		os=-proelf
+ 		;;
+@@ -1684,19 +1772,16 @@ case $basic_machine in
+ 				vendor=apple
+ 				;;
+ 			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ 				vendor=atari
+ 				;;
+ 			-vos*)
+ 				vendor=stratus
+ 				;;
+-			*-android*|*-linuxandroid*)
+-				vendor=linux-
+-				;;
+ 		esac
+ 		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ 		;;
+ esac
+ 
+ echo $basic_machine$os
+ exit
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-ppc64le-javascript.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,105 @@
+# HG changeset patch
+# Parent e6f9fc7c1611990ed9fdafd3ff19c79fd356a1d6
+# User Ulrich Weigand <uweigand@de.ibm.com>
+Bug 976648 - powerpc64le-linux support - JavaScript build/config
+
+diff --git a/js/src/assembler/wtf/Platform.h b/js/src/assembler/wtf/Platform.h
+--- a/js/src/assembler/wtf/Platform.h
++++ b/js/src/assembler/wtf/Platform.h
+@@ -160,26 +160,32 @@
+ /* WTF_CPU_PPC - PowerPC 32-bit */
+ #if   defined(__ppc__)     \
+     || defined(__PPC__)     \
+     || defined(__powerpc__) \
+     || defined(__powerpc)   \
+     || defined(__POWERPC__) \
+     || defined(_M_PPC)      \
+     || defined(__PPC)
++#if !defined(__ppc64__) && !defined(__PPC64__)
+ #define WTF_CPU_PPC 1
++#endif
++#if !defined(__LITTLE_ENDIAN__)
+ #define WTF_CPU_BIG_ENDIAN 1
+ #endif
++#endif
+ 
+ /* WTF_CPU_PPC64 - PowerPC 64-bit */
+ #if   defined(__ppc64__) \
+     || defined(__PPC64__)
+ #define WTF_CPU_PPC64 1
++#if !defined(__LITTLE_ENDIAN__)
+ #define WTF_CPU_BIG_ENDIAN 1
+ #endif
++#endif
+ 
+ /* WTF_CPU_SH4 - SuperH SH-4 */
+ #if defined(__SH4__)
+ #define WTF_CPU_SH4 1
+ #endif
+ 
+ /* WTF_CPU_SPARC32 - SPARC 32-bit */
+ #if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8)
+diff --git a/js/src/configure.in b/js/src/configure.in
+--- a/js/src/configure.in
++++ b/js/src/configure.in
+@@ -923,17 +923,17 @@ esac
+ 
+ # Only set CPU_ARCH if we recognize the value of OS_TEST
+ 
+ case "$OS_TEST" in
+ *86 | i86pc)
+     CPU_ARCH=x86
+     ;;
+ 
+-powerpc64 | ppc64)
++powerpc64 | ppc64 | powerpc64le | ppc64le)
+     CPU_ARCH=ppc64
+     ;;
+ 
+ powerpc | ppc | rs6000)
+     CPU_ARCH=ppc
+     ;;
+ 
+ Alpha | alpha | ALPHA)
+diff --git a/js/src/jscpucfg.h b/js/src/jscpucfg.h
+--- a/js/src/jscpucfg.h
++++ b/js/src/jscpucfg.h
+@@ -22,17 +22,17 @@
+ 
+ # ifdef __WATCOMC__
+ #  define HAVE_VA_LIST_AS_ARRAY 1
+ # endif
+ 
+ # define IS_LITTLE_ENDIAN 1
+ # undef  IS_BIG_ENDIAN
+ 
+-#elif defined(__APPLE__)
++#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__)
+ # if __LITTLE_ENDIAN__
+ #  define IS_LITTLE_ENDIAN 1
+ #  undef  IS_BIG_ENDIAN
+ # elif __BIG_ENDIAN__
+ #  undef  IS_LITTLE_ENDIAN
+ #  define IS_BIG_ENDIAN 1
+ # endif
+ 
+@@ -84,18 +84,17 @@
+ #  if defined(_STACK_GROWS_UPWARD)
+ #   define JS_STACK_GROWTH_DIRECTION (1)
+ #  elif defined(_STACK_GROWS_DOWNWARD)
+ #   define JS_STACK_GROWTH_DIRECTION (-1)
+ #  endif
+ # endif
+ 
+ #elif defined(__sparc) || defined(__sparc__) || \
+-      defined(_POWER) || defined(__powerpc__) || \
+-      defined(__ppc__) || defined(__hppa) || \
++      defined(_POWER) || defined(__hppa) || \
+       defined(_MIPSEB) || defined(_BIG_ENDIAN)
+ /* IA64 running HP-UX will have _BIG_ENDIAN defined.
+  * IA64 running Linux will have endian.h and be handled above.
+  */
+ # undef IS_LITTLE_ENDIAN
+ # define IS_BIG_ENDIAN 1
+ 
+ #else /* !defined(__sparc) && !defined(__sparc__) && ... */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-ppc64le-libffi.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,3206 @@
+# HG changeset patch
+# Parent 16cf73a02802e3b4a77ccd77794346441638e2a7
+# User Ulrich Weigand <uweigand@de.ibm.com>
+Bug 976648 - powerpc64le-linux support - libffi backport
+
+diff --git a/js/src/ctypes/libffi/aclocal.m4 b/js/src/ctypes/libffi/aclocal.m4
+--- a/js/src/ctypes/libffi/aclocal.m4
++++ b/js/src/ctypes/libffi/aclocal.m4
+@@ -1277,31 +1277,34 @@ ia64-*-hpux*)
+ 	  LD="${LD-ld} -64"
+ 	  ;;
+       esac
+     fi
+   fi
+   rm -rf conftest*
+   ;;
+ 
+-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+   # Find out which ABI we are using.
+   echo 'int i;' > conftest.$ac_ext
+   if AC_TRY_EVAL(ac_compile); then
+     case `/usr/bin/file conftest.o` in
+       *32-bit*)
+ 	case $host in
+ 	  x86_64-*kfreebsd*-gnu)
+ 	    LD="${LD-ld} -m elf_i386_fbsd"
+ 	    ;;
+ 	  x86_64-*linux*)
+ 	    LD="${LD-ld} -m elf_i386"
+ 	    ;;
+-	  ppc64-*linux*|powerpc64-*linux*)
++	  powerpc64le-*linux*)
++	    LD="${LD-ld} -m elf32lppclinux"
++	    ;;
++	  powerpc64-*linux*)
+ 	    LD="${LD-ld} -m elf32ppclinux"
+ 	    ;;
+ 	  s390x-*linux*)
+ 	    LD="${LD-ld} -m elf_s390"
+ 	    ;;
+ 	  sparc64-*linux*)
+ 	    LD="${LD-ld} -m elf32_sparc"
+ 	    ;;
+@@ -1310,17 +1313,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*
+       *64-bit*)
+ 	case $host in
+ 	  x86_64-*kfreebsd*-gnu)
+ 	    LD="${LD-ld} -m elf_x86_64_fbsd"
+ 	    ;;
+ 	  x86_64-*linux*)
+ 	    LD="${LD-ld} -m elf_x86_64"
+ 	    ;;
+-	  ppc*-*linux*|powerpc*-*linux*)
++	  powerpcle-*linux*)
++	    LD="${LD-ld} -m elf64lppc"
++	    ;;
++	  powerpc-*linux*)
+ 	    LD="${LD-ld} -m elf64ppc"
+ 	    ;;
+ 	  s390*-*linux*|s390*-*tpf*)
+ 	    LD="${LD-ld} -m elf64_s390"
+ 	    ;;
+ 	  sparc*-*linux*)
+ 	    LD="${LD-ld} -m elf64_sparc"
+ 	    ;;
+diff --git a/js/src/ctypes/libffi/configure b/js/src/ctypes/libffi/configure
+--- a/js/src/ctypes/libffi/configure
++++ b/js/src/ctypes/libffi/configure
+@@ -6293,17 +6293,17 @@ ia64-*-hpux*)
+ 	  LD="${LD-ld} -64"
+ 	  ;;
+       esac
+     fi
+   fi
+   rm -rf conftest*
+   ;;
+ 
+-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+   # Find out which ABI we are using.
+   echo 'int i;' > conftest.$ac_ext
+   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+   (eval $ac_compile) 2>&5
+   ac_status=$?
+   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+   test $ac_status = 0; }; then
+@@ -6311,17 +6311,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*
+       *32-bit*)
+ 	case $host in
+ 	  x86_64-*kfreebsd*-gnu)
+ 	    LD="${LD-ld} -m elf_i386_fbsd"
+ 	    ;;
+ 	  x86_64-*linux*)
+ 	    LD="${LD-ld} -m elf_i386"
+ 	    ;;
+-	  ppc64-*linux*|powerpc64-*linux*)
++	  powerpc64le-*linux*)
++	    LD="${LD-ld} -m elf32lppclinux"
++	    ;;
++	  powerpc64-*linux*)
+ 	    LD="${LD-ld} -m elf32ppclinux"
+ 	    ;;
+ 	  s390x-*linux*)
+ 	    LD="${LD-ld} -m elf_s390"
+ 	    ;;
+ 	  sparc64-*linux*)
+ 	    LD="${LD-ld} -m elf32_sparc"
+ 	    ;;
+@@ -6330,17 +6333,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*
+       *64-bit*)
+ 	case $host in
+ 	  x86_64-*kfreebsd*-gnu)
+ 	    LD="${LD-ld} -m elf_x86_64_fbsd"
+ 	    ;;
+ 	  x86_64-*linux*)
+ 	    LD="${LD-ld} -m elf_x86_64"
+ 	    ;;
+-	  ppc*-*linux*|powerpc*-*linux*)
++	  powerpcle-*linux*)
++	    LD="${LD-ld} -m elf64lppc"
++	    ;;
++	  powerpc-*linux*)
+ 	    LD="${LD-ld} -m elf64ppc"
+ 	    ;;
+ 	  s390*-*linux*|s390*-*tpf*)
+ 	    LD="${LD-ld} -m elf64_s390"
+ 	    ;;
+ 	  sparc*-*linux*)
+ 	    LD="${LD-ld} -m elf64_sparc"
+ 	    ;;
+diff --git a/js/src/ctypes/libffi/m4/libtool.m4 b/js/src/ctypes/libffi/m4/libtool.m4
+--- a/js/src/ctypes/libffi/m4/libtool.m4
++++ b/js/src/ctypes/libffi/m4/libtool.m4
+@@ -1262,31 +1262,34 @@ ia64-*-hpux*)
+ 	  LD="${LD-ld} -64"
+ 	  ;;
+       esac
+     fi
+   fi
+   rm -rf conftest*
+   ;;
+ 
+-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
++x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+   # Find out which ABI we are using.
+   echo 'int i;' > conftest.$ac_ext
+   if AC_TRY_EVAL(ac_compile); then
+     case `/usr/bin/file conftest.o` in
+       *32-bit*)
+ 	case $host in
+ 	  x86_64-*kfreebsd*-gnu)
+ 	    LD="${LD-ld} -m elf_i386_fbsd"
+ 	    ;;
+ 	  x86_64-*linux*)
+ 	    LD="${LD-ld} -m elf_i386"
+ 	    ;;
+-	  ppc64-*linux*|powerpc64-*linux*)
++	  powerpc64le-*linux*)
++	    LD="${LD-ld} -m elf32lppclinux"
++	    ;;
++	  powerpc64-*linux*)
+ 	    LD="${LD-ld} -m elf32ppclinux"
+ 	    ;;
+ 	  s390x-*linux*)
+ 	    LD="${LD-ld} -m elf_s390"
+ 	    ;;
+ 	  sparc64-*linux*)
+ 	    LD="${LD-ld} -m elf32_sparc"
+ 	    ;;
+@@ -1295,17 +1298,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*
+       *64-bit*)
+ 	case $host in
+ 	  x86_64-*kfreebsd*-gnu)
+ 	    LD="${LD-ld} -m elf_x86_64_fbsd"
+ 	    ;;
+ 	  x86_64-*linux*)
+ 	    LD="${LD-ld} -m elf_x86_64"
+ 	    ;;
+-	  ppc*-*linux*|powerpc*-*linux*)
++	  powerpcle-*linux*)
++	    LD="${LD-ld} -m elf64lppc"
++	    ;;
++	  powerpc-*linux*)
+ 	    LD="${LD-ld} -m elf64ppc"
+ 	    ;;
+ 	  s390*-*linux*|s390*-*tpf*)
+ 	    LD="${LD-ld} -m elf64_s390"
+ 	    ;;
+ 	  sparc*-*linux*)
+ 	    LD="${LD-ld} -m elf64_sparc"
+ 	    ;;
+diff --git a/js/src/ctypes/libffi/src/powerpc/ffi.c b/js/src/ctypes/libffi/src/powerpc/ffi.c
+--- a/js/src/ctypes/libffi/src/powerpc/ffi.c
++++ b/js/src/ctypes/libffi/src/powerpc/ffi.c
+@@ -1,12 +1,14 @@
+ /* -----------------------------------------------------------------------
+-   ffi.c - Copyright (c) 1998 Geoffrey Keating
+-   Copyright (C) 2007, 2008 Free Software Foundation, Inc
+-   Copyright (C) 2008 Red Hat, Inc
++   ffi.c - Copyright (C) 2011 Anthony Green
++           Copyright (C) 2011 Kyle Moffett
++           Copyright (C) 2008 Red Hat, Inc
++           Copyright (C) 2007, 2008 Free Software Foundation, Inc
++	   Copyright (c) 1998 Geoffrey Keating
+ 
+    PowerPC Foreign Function Interface
+ 
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    ``Software''), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+@@ -34,42 +36,39 @@
+ 
+ extern void ffi_closure_SYSV (void);
+ extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
+ 
+ enum {
+   /* The assembly depends on these exact flags.  */
+   FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
+   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
++#ifndef __NO_FPRS__
+   FLAG_RETURNS_FP       = 1 << (31-29),
++#endif
+   FLAG_RETURNS_64BITS   = 1 << (31-28),
+ 
+   FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
+-  FLAG_SYSV_SMST_R4     = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
+-					   structs.  */
+-  FLAG_SYSV_SMST_R3     = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
+-					   structs.  */
+-  /* Bits (31-24) through (31-19) store shift value for SMST */
+ 
+   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
++  FLAG_ARG_NEEDS_PSAVE  = FLAG_ARG_NEEDS_COPY, /* Used by ELFv2 */
++#ifndef __NO_FPRS__
+   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
++#endif
+   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
+   FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+ };
+ 
+ /* About the SYSV ABI.  */
+-unsigned int NUM_GPR_ARG_REGISTERS = 8;
++#define ASM_NEEDS_REGISTERS 4
++#define NUM_GPR_ARG_REGISTERS 8
+ #ifndef __NO_FPRS__
+-unsigned int NUM_FPR_ARG_REGISTERS = 8;
+-#else
+-unsigned int NUM_FPR_ARG_REGISTERS = 0;
++# define NUM_FPR_ARG_REGISTERS 8
+ #endif
+ 
+-enum { ASM_NEEDS_REGISTERS = 4 };
+-
+ /* ffi_prep_args_SYSV is called by the assembly routine once stack space
+    has been allocated for the function's arguments.
+ 
+    The stack layout we want looks like this:
+ 
+    |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
+    |--------------------------------------------|
+    |   Previous backchain pointer	4	|       stack pointer here
+@@ -108,100 +107,119 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
+   /* 'stacktop' points at the previous backchain pointer.  */
+   valp stacktop;
+ 
+   /* 'gpr_base' points at the space for gpr3, and grows upwards as
+      we use GPR registers.  */
+   valp gpr_base;
+   int intarg_count;
+ 
++#ifndef __NO_FPRS__
+   /* 'fpr_base' points at the space for fpr1, and grows upwards as
+      we use FPR registers.  */
+   valp fpr_base;
+   int fparg_count;
++#endif
+ 
+   /* 'copy_space' grows down as we put structures in it.  It should
+      stay 16-byte aligned.  */
+   valp copy_space;
+ 
+   /* 'next_arg' grows up as we put parameters in it.  */
+   valp next_arg;
+ 
+-  int i, ii MAYBE_UNUSED;
++  int i;
+   ffi_type **ptr;
++#ifndef __NO_FPRS__
+   double double_tmp;
++#endif
+   union {
+     void **v;
+     char **c;
+     signed char **sc;
+     unsigned char **uc;
+     signed short **ss;
+     unsigned short **us;
+     unsigned int **ui;
+     long long **ll;
+     float **f;
+     double **d;
+   } p_argv;
+   size_t struct_copy_size;
+   unsigned gprvalue;
+ 
+-  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+-    NUM_FPR_ARG_REGISTERS = 0;
+-
+   stacktop.c = (char *) stack + bytes;
+   gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
+   intarg_count = 0;
++#ifndef __NO_FPRS__
+   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
+   fparg_count = 0;
+   copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
++#else
++  copy_space.c = gpr_base.c;
++#endif
+   next_arg.u = stack + 2;
+ 
+   /* Check that everything starts aligned properly.  */
+-  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
+-  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
+-  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
++  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
++  FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
++  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
+   FFI_ASSERT ((bytes & 0xF) == 0);
+   FFI_ASSERT (copy_space.c >= next_arg.c);
+ 
+   /* Deal with return values that are actually pass-by-reference.  */
+   if (flags & FLAG_RETVAL_REFERENCE)
+     {
+       *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
+       intarg_count++;
+     }
+ 
+   /* Now for the arguments.  */
+   p_argv.v = ecif->avalue;
+   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+        i > 0;
+        i--, ptr++, p_argv.v++)
+     {
+-      switch ((*ptr)->type)
+-	{
++      unsigned short typenum = (*ptr)->type;
++
++      /* We may need to handle some values depending on ABI */
++      if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) {
++		if (typenum == FFI_TYPE_FLOAT)
++			typenum = FFI_TYPE_UINT32;
++		if (typenum == FFI_TYPE_DOUBLE)
++			typenum = FFI_TYPE_UINT64;
++		if (typenum == FFI_TYPE_LONGDOUBLE)
++			typenum = FFI_TYPE_UINT128;
++      } else if (ecif->cif->abi != FFI_LINUX) {
++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
++		if (typenum == FFI_TYPE_LONGDOUBLE)
++			typenum = FFI_TYPE_STRUCT;
++#endif
++      }
++
++      /* Now test the translated value */
++      switch (typenum) {
++#ifndef __NO_FPRS__
+ 	case FFI_TYPE_FLOAT:
+ 	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
+-	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	    goto soft_float_prep;
+ 	  double_tmp = **p_argv.f;
+ 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ 	    {
+ 	      *next_arg.f = (float) double_tmp;
+ 	      next_arg.u += 1;
+ 	      intarg_count++;
+ 	    }
+ 	  else
+ 	    *fpr_base.d++ = double_tmp;
+ 	  fparg_count++;
+ 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ 	  break;
+ 
+ 	case FFI_TYPE_DOUBLE:
+ 	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
+-	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	    goto soft_double_prep;
+ 	  double_tmp = **p_argv.d;
+ 
+ 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ 	    {
+ 	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
+ 		  && intarg_count % 2 != 0)
+ 		{
+ 		  intarg_count++;
+@@ -213,53 +231,16 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
+ 	  else
+ 	    *fpr_base.d++ = double_tmp;
+ 	  fparg_count++;
+ 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ 	  break;
+ 
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ 	case FFI_TYPE_LONGDOUBLE:
+-	  if ((ecif->cif->abi != FFI_LINUX)
+-		&& (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
+-	    goto do_struct;
+-	  /* The soft float ABI for long doubles works like this,
+-	     a long double is passed in four consecutive gprs if available.
+-	     A maximum of 2 long doubles can be passed in gprs.
+-	     If we do not have 4 gprs left, the long double is passed on the
+-	     stack, 4-byte aligned.  */
+-	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	    {
+-	      unsigned int int_tmp = (*p_argv.ui)[0];
+-	      if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
+-		{
+-		  if (intarg_count < NUM_GPR_ARG_REGISTERS)
+-		    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
+-		  *next_arg.u = int_tmp;
+-		  next_arg.u++;
+-		  for (ii = 1; ii < 4; ii++)
+-		    {
+-		      int_tmp = (*p_argv.ui)[ii];
+-		      *next_arg.u = int_tmp;
+-		      next_arg.u++;
+-		    }
+-		}
+-	      else
+-		{
+-		  *gpr_base.u++ = int_tmp;
+-		  for (ii = 1; ii < 4; ii++)
+-		    {
+-		      int_tmp = (*p_argv.ui)[ii];
+-		      *gpr_base.u++ = int_tmp;
+-		    }
+-		}
+-	      intarg_count +=4;
+-	    }
+-	  else
+-	    {
+ 	      double_tmp = (*p_argv.d)[0];
+ 
+ 	      if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
+ 		{
+ 		  if (intarg_count >= NUM_GPR_ARG_REGISTERS
+ 		      && intarg_count % 2 != 0)
+ 		    {
+ 		      intarg_count++;
+@@ -275,23 +256,50 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
+ 		{
+ 		  *fpr_base.d++ = double_tmp;
+ 		  double_tmp = (*p_argv.d)[1];
+ 		  *fpr_base.d++ = double_tmp;
+ 		}
+ 
+ 	      fparg_count += 2;
+ 	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+-	    }
+ 	  break;
+ #endif
++#endif /* have FPRs */
++
++	/*
++	 * The soft float ABI for long doubles works like this, a long double
++	 * is passed in four consecutive GPRs if available.  A maximum of 2
++	 * long doubles can be passed in gprs.  If we do not have 4 GPRs
++	 * left, the long double is passed on the stack, 4-byte aligned.
++	 */
++	case FFI_TYPE_UINT128: {
++		unsigned int int_tmp = (*p_argv.ui)[0];
++		unsigned int ii;
++		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) {
++			if (intarg_count < NUM_GPR_ARG_REGISTERS)
++				intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
++			*(next_arg.u++) = int_tmp;
++			for (ii = 1; ii < 4; ii++) {
++				int_tmp = (*p_argv.ui)[ii];
++				*(next_arg.u++) = int_tmp;
++			}
++		} else {
++			*(gpr_base.u++) = int_tmp;
++			for (ii = 1; ii < 4; ii++) {
++				int_tmp = (*p_argv.ui)[ii];
++				*(gpr_base.u++) = int_tmp;
++			}
++		}
++		intarg_count += 4;
++		break;
++	}
+ 
+ 	case FFI_TYPE_UINT64:
+ 	case FFI_TYPE_SINT64:
+-	soft_double_prep:
+ 	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
+ 	    intarg_count++;
+ 	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+ 	    {
+ 	      if (intarg_count % 2 != 0)
+ 		{
+ 		  intarg_count++;
+ 		  next_arg.u++;
+@@ -314,19 +322,16 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
+ 		  gpr_base.u++;
+ 		}
+ 	      *gpr_base.ll++ = **p_argv.ll;
+ 	    }
+ 	  intarg_count += 2;
+ 	  break;
+ 
+ 	case FFI_TYPE_STRUCT:
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-	do_struct:
+-#endif
+ 	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
+ 	  copy_space.c -= struct_copy_size;
+ 	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
+ 
+ 	  gprvalue = (unsigned long) copy_space.c;
+ 
+ 	  FFI_ASSERT (copy_space.c > next_arg.c);
+ 	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
+@@ -344,45 +349,91 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
+ 	case FFI_TYPE_SINT16:
+ 	  gprvalue = **p_argv.ss;
+ 	  goto putgpr;
+ 
+ 	case FFI_TYPE_INT:
+ 	case FFI_TYPE_UINT32:
+ 	case FFI_TYPE_SINT32:
+ 	case FFI_TYPE_POINTER:
+-	soft_float_prep:
+ 
+ 	  gprvalue = **p_argv.ui;
+ 
+ 	putgpr:
+ 	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+ 	    *next_arg.u++ = gprvalue;
+ 	  else
+ 	    *gpr_base.u++ = gprvalue;
+ 	  intarg_count++;
+ 	  break;
+ 	}
+     }
+ 
+   /* Check that we didn't overrun the stack...  */
+   FFI_ASSERT (copy_space.c >= next_arg.c);
+   FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
++  /* The assert below is testing that the number of integer arguments agrees
++     with the number found in ffi_prep_cif_machdep().  However, intarg_count
++     is incremented whenever we place an FP arg on the stack, so account for
++     that before our assert test.  */
++#ifndef __NO_FPRS__
++  if (fparg_count > NUM_FPR_ARG_REGISTERS)
++    intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS;
+   FFI_ASSERT (fpr_base.u
+ 	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
++#endif
+   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+ }
+ 
+ /* About the LINUX64 ABI.  */
+ enum {
+   NUM_GPR_ARG_REGISTERS64 = 8,
+   NUM_FPR_ARG_REGISTERS64 = 13
+ };
+ enum { ASM_NEEDS_REGISTERS64 = 4 };
+ 
++#if _CALL_ELF == 2
++static unsigned int
++discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
++{
++  switch (t->type)
++    {
++    case FFI_TYPE_FLOAT:
++    case FFI_TYPE_DOUBLE:
++      *elnum = 1;
++      return (int) t->type;
++
++    case FFI_TYPE_STRUCT:;
++      {
++	unsigned int base_elt = 0, total_elnum = 0;
++	ffi_type **el = t->elements;
++	while (*el)
++	  {
++	    unsigned int el_elt, el_elnum = 0;
++	    el_elt = discover_homogeneous_aggregate (*el, &el_elnum);
++	    if (el_elt == 0
++		|| (base_elt && base_elt != el_elt))
++	      return 0;
++	    base_elt = el_elt;
++	    total_elnum += el_elnum;
++	    if (total_elnum > 8)
++	      return 0;
++	    el++;
++	  }
++	*elnum = total_elnum;
++	return base_elt;
++      }
++
++    default:
++      return 0;
++    }
++}
++#endif
++
++
+ /* ffi_prep_args64 is called by the assembly routine once stack space
+    has been allocated for the function's arguments.
+ 
+    The stack layout we want looks like this:
+ 
+    |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses
+    |--------------------------------------------|
+    |   CR save area			8bytes	|
+@@ -418,141 +469,216 @@ ffi_prep_args64 (extended_cif *ecif, uns
+   const unsigned long bytes = ecif->cif->bytes;
+   const unsigned long flags = ecif->cif->flags;
+ 
+   typedef union {
+     char *c;
+     unsigned long *ul;
+     float *f;
+     double *d;
++    size_t p;
+   } valp;
+ 
+   /* 'stacktop' points at the previous backchain pointer.  */
+   valp stacktop;
+ 
+   /* 'next_arg' points at the space for gpr3, and grows upwards as
+      we use GPR registers, then continues at rest.  */
+   valp gpr_base;
+   valp gpr_end;
+   valp rest;
+   valp next_arg;
+ 
+   /* 'fpr_base' points at the space for fpr3, and grows upwards as
+      we use FPR registers.  */
+   valp fpr_base;
+-  int fparg_count;
++  unsigned int fparg_count;
+ 
+-  int i, words;
++  unsigned int i, words, nargs, nfixedargs;
+   ffi_type **ptr;
+   double double_tmp;
+   union {
+     void **v;
+     char **c;
+     signed char **sc;
+     unsigned char **uc;
+     signed short **ss;
+     unsigned short **us;
+     signed int **si;
+     unsigned int **ui;
+     unsigned long **ul;
+     float **f;
+     double **d;
+   } p_argv;
+   unsigned long gprvalue;
++#ifdef __STRUCT_PARM_ALIGN__
++  unsigned long align;
++#endif
+ 
+   stacktop.c = (char *) stack + bytes;
+   gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
+   gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
++#if _CALL_ELF == 2
++  rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64;
++#else
+   rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
++#endif
+   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
+   fparg_count = 0;
+   next_arg.ul = gpr_base.ul;
+ 
+   /* Check that everything starts aligned properly.  */
+   FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
+   FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
+   FFI_ASSERT ((bytes & 0xF) == 0);
+ 
+   /* Deal with return values that are actually pass-by-reference.  */
+   if (flags & FLAG_RETVAL_REFERENCE)
+     *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
+ 
+   /* Now for the arguments.  */
+   p_argv.v = ecif->avalue;
+-  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+-       i > 0;
+-       i--, ptr++, p_argv.v++)
++  nargs = ecif->cif->nargs;
++  nfixedargs = ecif->cif->nfixedargs;
++  for (ptr = ecif->cif->arg_types, i = 0;
++       i < nargs;
++       i++, ptr++, p_argv.v++)
+     {
++      unsigned int elt, elnum;
++
+       switch ((*ptr)->type)
+ 	{
+ 	case FFI_TYPE_FLOAT:
+ 	  double_tmp = **p_argv.f;
+-	  *next_arg.f = (float) double_tmp;
++	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
++	    *fpr_base.d++ = double_tmp;
++	  else
++	    *next_arg.f = (float) double_tmp;
+ 	  if (++next_arg.ul == gpr_end.ul)
+ 	    next_arg.ul = rest.ul;
+-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+-	    *fpr_base.d++ = double_tmp;
+ 	  fparg_count++;
+ 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ 	  break;
+ 
+ 	case FFI_TYPE_DOUBLE:
+ 	  double_tmp = **p_argv.d;
+-	  *next_arg.d = double_tmp;
++	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
++	    *fpr_base.d++ = double_tmp;
++	  else
++	    *next_arg.d = double_tmp;
+ 	  if (++next_arg.ul == gpr_end.ul)
+ 	    next_arg.ul = rest.ul;
+-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+-	    *fpr_base.d++ = double_tmp;
+ 	  fparg_count++;
+ 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ 	  break;
+ 
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ 	case FFI_TYPE_LONGDOUBLE:
+ 	  double_tmp = (*p_argv.d)[0];
+-	  *next_arg.d = double_tmp;
++	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
++	    *fpr_base.d++ = double_tmp;
++	  else
++	    *next_arg.d = double_tmp;
+ 	  if (++next_arg.ul == gpr_end.ul)
+ 	    next_arg.ul = rest.ul;
+-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+-	    *fpr_base.d++ = double_tmp;
+ 	  fparg_count++;
+ 	  double_tmp = (*p_argv.d)[1];
+-	  *next_arg.d = double_tmp;
++	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
++	    *fpr_base.d++ = double_tmp;
++	  else
++	    *next_arg.d = double_tmp;
+ 	  if (++next_arg.ul == gpr_end.ul)
+ 	    next_arg.ul = rest.ul;
+-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
+-	    *fpr_base.d++ = double_tmp;
+ 	  fparg_count++;
+ 	  FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
+ 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
+ 	  break;
+ #endif
+ 
+ 	case FFI_TYPE_STRUCT:
+-	  words = ((*ptr)->size + 7) / 8;
+-	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
++#ifdef __STRUCT_PARM_ALIGN__
++	  align = (*ptr)->alignment;
++	  if (align > __STRUCT_PARM_ALIGN__)
++	    align = __STRUCT_PARM_ALIGN__;
++	  if (align > 1)
++	    next_arg.p = ALIGN (next_arg.p, align);
++#endif
++	  elt = 0;
++#if _CALL_ELF == 2
++	  elt = discover_homogeneous_aggregate (*ptr, &elnum);
++#endif
++	  if (elt)
+ 	    {
+-	      size_t first = gpr_end.c - next_arg.c;
+-	      memcpy (next_arg.c, *p_argv.c, first);
+-	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
+-	      next_arg.c = rest.c + words * 8 - first;
++	      union {
++		void *v;
++		float *f;
++		double *d;
++	      } arg;
++
++	      arg.v = *p_argv.v;
++	      if (elt == FFI_TYPE_FLOAT)
++		{
++		  do
++		    {
++		      double_tmp = *arg.f++;
++		      if (fparg_count < NUM_FPR_ARG_REGISTERS64
++			  && i < nfixedargs)
++			*fpr_base.d++ = double_tmp;
++		      else
++			*next_arg.f = (float) double_tmp;
++		      if (++next_arg.f == gpr_end.f)
++			next_arg.f = rest.f;
++		      fparg_count++;
++		    }
++		  while (--elnum != 0);
++		  if ((next_arg.p & 3) != 0)
++		    {
++		      if (++next_arg.f == gpr_end.f)
++			next_arg.f = rest.f;
++		    }
++		}
++	      else
++		do
++		  {
++		    double_tmp = *arg.d++;
++		    if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
++		      *fpr_base.d++ = double_tmp;
++		    else
++		      *next_arg.d = double_tmp;
++		    if (++next_arg.d == gpr_end.d)
++		      next_arg.d = rest.d;
++		    fparg_count++;
++		  }
++		while (--elnum != 0);
+ 	    }
+ 	  else
+ 	    {
+-	      char *where = next_arg.c;
++	      words = ((*ptr)->size + 7) / 8;
++	      if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
++		{
++		  size_t first = gpr_end.c - next_arg.c;
++		  memcpy (next_arg.c, *p_argv.c, first);
++		  memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
++		  next_arg.c = rest.c + words * 8 - first;
++		}
++	      else
++		{
++		  char *where = next_arg.c;
+ 
+-	      /* Structures with size less than eight bytes are passed
+-		 left-padded.  */
+-	      if ((*ptr)->size < 8)
+-		where += 8 - (*ptr)->size;
+-
+-	      memcpy (where, *p_argv.c, (*ptr)->size);
+-	      next_arg.ul += words;
+-	      if (next_arg.ul == gpr_end.ul)
+-		next_arg.ul = rest.ul;
++#ifndef __LITTLE_ENDIAN__
++		  /* Structures with size less than eight bytes are passed
++		     left-padded.  */
++		  if ((*ptr)->size < 8)
++		    where += 8 - (*ptr)->size;
++#endif
++		  memcpy (where, *p_argv.c, (*ptr)->size);
++		  next_arg.ul += words;
++		  if (next_arg.ul == gpr_end.ul)
++		    next_arg.ul = rest.ul;
++		}
+ 	    }
+ 	  break;
+ 
+ 	case FFI_TYPE_UINT8:
+ 	  gprvalue = **p_argv.uc;
+ 	  goto putgpr;
+ 	case FFI_TYPE_SINT8:
+ 	  gprvalue = **p_argv.sc;
+@@ -586,53 +712,55 @@ ffi_prep_args64 (extended_cif *ecif, uns
+   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
+ 	      || (next_arg.ul >= gpr_base.ul
+ 		  && next_arg.ul <= gpr_base.ul + 4));
+ }
+ 
+ 
+ 
+ /* Perform machine dependent cif processing */
+-ffi_status
+-ffi_prep_cif_machdep (ffi_cif *cif)
++static ffi_status
++ffi_prep_cif_machdep_core (ffi_cif *cif)
+ {
+   /* All this is for the SYSV and LINUX64 ABI.  */
+-  int i;
+   ffi_type **ptr;
+   unsigned bytes;
+-  int fparg_count = 0, intarg_count = 0;
+-  unsigned flags = 0;
++  unsigned i, fparg_count = 0, intarg_count = 0;
++  unsigned flags = cif->flags;
+   unsigned struct_copy_size = 0;
+   unsigned type = cif->rtype->type;
+   unsigned size = cif->rtype->size;
+ 
+-  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-    NUM_FPR_ARG_REGISTERS = 0;
+-
++  /* The machine-independent calculation of cif->bytes doesn't work
++     for us.  Redo the calculation.  */
+   if (cif->abi != FFI_LINUX64)
+     {
+-      /* All the machine-independent calculation of cif->bytes will be wrong.
+-	 Redo the calculation for SYSV.  */
+-
+       /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
+       bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
+ 
+       /* Space for the GPR registers.  */
+       bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
+     }
+   else
+     {
+       /* 64-bit ABI.  */
++#if _CALL_ELF == 2
++      /* Space for backchain, CR, LR, TOC and the asm's temp regs.  */
++      bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long);
+ 
++      /* Space for the general registers.  */
++      bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long);
++#else
+       /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
+ 	 regs.  */
+       bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
+ 
+       /* Space for the mandatory parm save area and general registers.  */
+       bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
++#endif
+     }
+ 
+   /* Return value handling.  The rules for SYSV are as follows:
+      - 32-bit (or less) integer values are returned in gpr3;
+      - Structures of size <= 4 bytes also returned in gpr3;
+      - 64-bit integer values and structures between 5 and 8 bytes are returned
+      in gpr3 and gpr4;
+      - Single/double FP values are returned in fpr1;
+@@ -641,71 +769,93 @@ ffi_prep_cif_machdep (ffi_cif *cif)
+      - long doubles (if not equivalent to double) are returned in
+      fpr1,fpr2 for Linux and as for large structs for SysV.
+      For LINUX64:
+      - integer values in gpr3;
+      - Structures/Unions by reference;
+      - Single/double FP values in fpr1, long double in fpr1,fpr2.
+      - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
+      - soft-float long doubles are returned in gpr3-gpr6.  */
++  /* First translate for softfloat/nonlinux */
++  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
++    {
++      if (type == FFI_TYPE_FLOAT)
++	type = FFI_TYPE_UINT32;
++      if (type == FFI_TYPE_DOUBLE)
++	type = FFI_TYPE_UINT64;
++      if (type == FFI_TYPE_LONGDOUBLE)
++	type = FFI_TYPE_UINT128;
++    }
++  else if (cif->abi != FFI_LINUX
++	   && cif->abi != FFI_LINUX64)
++    {
++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
++      if (type == FFI_TYPE_LONGDOUBLE)
++	type = FFI_TYPE_STRUCT;
++#endif
++    }
++
+   switch (type)
+     {
++#ifndef __NO_FPRS__
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+     case FFI_TYPE_LONGDOUBLE:
+-      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
+-	&& cif->abi != FFI_LINUX_SOFT_FLOAT)
+-	goto byref;
+       flags |= FLAG_RETURNS_128BITS;
+       /* Fall through.  */
+ #endif
+     case FFI_TYPE_DOUBLE:
+       flags |= FLAG_RETURNS_64BITS;
+       /* Fall through.  */
+     case FFI_TYPE_FLOAT:
+-      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
+-      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
+-	flags |= FLAG_RETURNS_FP;
++      flags |= FLAG_RETURNS_FP;
+       break;
++#endif
+ 
++    case FFI_TYPE_UINT128:
++      flags |= FLAG_RETURNS_128BITS;
++      /* Fall through.  */
+     case FFI_TYPE_UINT64:
+     case FFI_TYPE_SINT64:
+       flags |= FLAG_RETURNS_64BITS;
+       break;
+ 
+     case FFI_TYPE_STRUCT:
+-      if (cif->abi == FFI_SYSV)
++      /*
++       * The final SYSV ABI says that structures smaller or equal 8 bytes
++       * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
++       * in memory.
++       *
++       * NOTE: The assembly code can safely assume that it just needs to
++       *       store both r3 and r4 into a 8-byte word-aligned buffer, as
++       *       we allocate a temporary buffer in ffi_call() if this flag is
++       *       set.
++       */
++      if (cif->abi == FFI_SYSV && size <= 8)
+ 	{
+-	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
+-	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
+-	     in memory.  */
+-
+-	  /* Treat structs with size <= 8 bytes.  */
+-	  if (size <= 8)
++	  flags |= FLAG_RETURNS_SMST;
++	  break;
++	}
++#if _CALL_ELF == 2
++      if (cif->abi == FFI_LINUX64)
++	{
++	  unsigned int elt, elnum;
++	  elt = discover_homogeneous_aggregate (cif->rtype, &elnum);
++	  if (elt)
++	    {
++	      if (elt == FFI_TYPE_DOUBLE)
++		flags |= FLAG_RETURNS_64BITS;
++	      flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST;
++	      break;
++	    }
++	  if (size <= 16)
+ 	    {
+ 	      flags |= FLAG_RETURNS_SMST;
+-	      /* These structs are returned in r3. We pack the type and the
+-		 precalculated shift value (needed in the sysv.S) into flags.
+-		 The same applies for the structs returned in r3/r4.  */
+-	      if (size <= 4)
+-		{
+-		  flags |= FLAG_SYSV_SMST_R3;
+-		  flags |= 8 * (4 - size) << 8;
+-		  break;
+-		}
+-	      /* These structs are returned in r3 and r4. See above.   */
+-	      if  (size <= 8)
+-		{
+-		  flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
+-		  flags |= 8 * (8 - size) << 8;
+-		  break;
+-		}
++	      break;
+ 	    }
+ 	}
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-    byref:
+ #endif
+       intarg_count++;
+       flags |= FLAG_RETVAL_REFERENCE;
+       /* Fall through.  */
+     case FFI_TYPE_VOID:
+       flags |= FLAG_RETURNS_NOTHING;
+       break;
+ 
+@@ -717,218 +867,334 @@ ffi_prep_cif_machdep (ffi_cif *cif)
+   if (cif->abi != FFI_LINUX64)
+     /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+        first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+        goes on the stack.  Structures and long doubles (if not equivalent
+        to double) are passed as a pointer to a copy of the structure.
+        Stuff on the stack needs to keep proper alignment.  */
+     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+       {
+-	switch ((*ptr)->type)
+-	  {
++	unsigned short typenum = (*ptr)->type;
++
++	/* We may need to handle some values depending on ABI */
++	if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
++		if (typenum == FFI_TYPE_FLOAT)
++			typenum = FFI_TYPE_UINT32;
++		if (typenum == FFI_TYPE_DOUBLE)
++			typenum = FFI_TYPE_UINT64;
++		if (typenum == FFI_TYPE_LONGDOUBLE)
++			typenum = FFI_TYPE_UINT128;
++	} else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
++		if (typenum == FFI_TYPE_LONGDOUBLE)
++			typenum = FFI_TYPE_STRUCT;
++#endif
++	}
++
++	switch (typenum) {
++#ifndef __NO_FPRS__
+ 	  case FFI_TYPE_FLOAT:
+-	    /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
+-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	      goto soft_float_cif;
+ 	    fparg_count++;
+ 	    /* floating singles are not 8-aligned on stack */
+ 	    break;
+ 
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ 	  case FFI_TYPE_LONGDOUBLE:
+-	    if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+-	      goto do_struct;
+-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	      {
+-		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
+-		  || intarg_count < NUM_GPR_ARG_REGISTERS)
+-		  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
+-		     a set of four consecutive gprs. If we have not enough,
+-		     we have to adjust the intarg_count value.  */
+-		  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
+-		intarg_count += 4;
+-		break;
+-	      }
+-	    else
+-	      fparg_count++;
++	    fparg_count++;
+ 	    /* Fall thru */
+ #endif
+ 	  case FFI_TYPE_DOUBLE:
+-	    /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
+-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	      goto soft_double_cif;
+ 	    fparg_count++;
+ 	    /* If this FP arg is going on the stack, it must be
+ 	       8-byte-aligned.  */
+ 	    if (fparg_count > NUM_FPR_ARG_REGISTERS
+ 		&& intarg_count >= NUM_GPR_ARG_REGISTERS
+ 		&& intarg_count % 2 != 0)
+ 	      intarg_count++;
+ 	    break;
++#endif
++	  case FFI_TYPE_UINT128:
++		/*
++		 * A long double in FFI_LINUX_SOFT_FLOAT can use only a set
++		 * of four consecutive gprs. If we do not have enough, we
++		 * have to adjust the intarg_count value.
++		 */
++		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
++				&& intarg_count < NUM_GPR_ARG_REGISTERS)
++			intarg_count = NUM_GPR_ARG_REGISTERS;
++		intarg_count += 4;
++		break;
+ 
+ 	  case FFI_TYPE_UINT64:
+ 	  case FFI_TYPE_SINT64:
+-	  soft_double_cif:
+ 	    /* 'long long' arguments are passed as two words, but
+ 	       either both words must fit in registers or both go
+ 	       on the stack.  If they go on the stack, they must
+ 	       be 8-byte-aligned.
+ 
+ 	       Also, only certain register pairs can be used for
+ 	       passing long long int -- specifically (r3,r4), (r5,r6),
+ 	       (r7,r8), (r9,r10).
+ 	    */
+ 	    if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+ 		|| intarg_count % 2 != 0)
+ 	      intarg_count++;
+ 	    intarg_count += 2;
+ 	    break;
+ 
+ 	  case FFI_TYPE_STRUCT:
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-	  do_struct:
+-#endif
+ 	    /* We must allocate space for a copy of these to enforce
+ 	       pass-by-value.  Pad the space up to a multiple of 16
+ 	       bytes (the maximum alignment required for anything under
+ 	       the SYSV ABI).  */
+ 	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
+ 	    /* Fall through (allocate space for the pointer).  */
+ 
+-	  default:
+-	  soft_float_cif:
++	  case FFI_TYPE_POINTER:
++	  case FFI_TYPE_INT:
++	  case FFI_TYPE_UINT32:
++	  case FFI_TYPE_SINT32:
++	  case FFI_TYPE_UINT16:
++	  case FFI_TYPE_SINT16:
++	  case FFI_TYPE_UINT8:
++	  case FFI_TYPE_SINT8:
+ 	    /* Everything else is passed as a 4-byte word in a GPR, either
+ 	       the object itself or a pointer to it.  */
+ 	    intarg_count++;
+ 	    break;
++	  default:
++		FFI_ASSERT (0);
+ 	  }
+       }
+   else
+     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+       {
++	unsigned int elt, elnum;
++#ifdef __STRUCT_PARM_ALIGN__
++	unsigned int align;
++#endif
++
+ 	switch ((*ptr)->type)
+ 	  {
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ 	  case FFI_TYPE_LONGDOUBLE:
+-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	      intarg_count += 4;
+-	    else
+-	      {
+-		fparg_count += 2;
+-		intarg_count += 2;
+-	      }
++	    fparg_count += 2;
++	    intarg_count += 2;
++	    if (fparg_count > NUM_FPR_ARG_REGISTERS64)
++	      flags |= FLAG_ARG_NEEDS_PSAVE;
+ 	    break;
+ #endif
+ 	  case FFI_TYPE_FLOAT:
+ 	  case FFI_TYPE_DOUBLE:
+ 	    fparg_count++;
+ 	    intarg_count++;
++	    if (fparg_count > NUM_FPR_ARG_REGISTERS64)
++	      flags |= FLAG_ARG_NEEDS_PSAVE;
+ 	    break;
+ 
+ 	  case FFI_TYPE_STRUCT:
++#ifdef __STRUCT_PARM_ALIGN__
++	    align = (*ptr)->alignment;
++	    if (align > __STRUCT_PARM_ALIGN__)
++	      align = __STRUCT_PARM_ALIGN__;
++	    align = align / 8;
++	    if (align > 1)
++	      intarg_count = ALIGN (intarg_count, align);
++#endif
+ 	    intarg_count += ((*ptr)->size + 7) / 8;
++	    elt = 0;
++#if _CALL_ELF == 2
++	    elt = discover_homogeneous_aggregate (*ptr, &elnum);
++#endif
++	    if (elt)
++	      {
++		fparg_count += elnum;
++		if (fparg_count > NUM_FPR_ARG_REGISTERS64)
++		  flags |= FLAG_ARG_NEEDS_PSAVE;
++	      }
++	    else
++	      {
++		if (intarg_count > NUM_GPR_ARG_REGISTERS64)
++		  flags |= FLAG_ARG_NEEDS_PSAVE;
++	      }
+ 	    break;
+ 
+-	  default:
++	  case FFI_TYPE_POINTER:
++	  case FFI_TYPE_UINT64:
++	  case FFI_TYPE_SINT64:
++	  case FFI_TYPE_INT:
++	  case FFI_TYPE_UINT32:
++	  case FFI_TYPE_SINT32:
++	  case FFI_TYPE_UINT16:
++	  case FFI_TYPE_SINT16:
++	  case FFI_TYPE_UINT8:
++	  case FFI_TYPE_SINT8:
+ 	    /* Everything else is passed as a 8-byte word in a GPR, either
+ 	       the object itself or a pointer to it.  */
+ 	    intarg_count++;
++	    if (intarg_count > NUM_GPR_ARG_REGISTERS64)
++	      flags |= FLAG_ARG_NEEDS_PSAVE;
+ 	    break;
++	  default:
++	    FFI_ASSERT (0);
+ 	  }
+       }
+ 
++#ifndef __NO_FPRS__
+   if (fparg_count != 0)
+     flags |= FLAG_FP_ARGUMENTS;
++#endif
+   if (intarg_count > 4)
+     flags |= FLAG_4_GPR_ARGUMENTS;
+   if (struct_copy_size != 0)
+     flags |= FLAG_ARG_NEEDS_COPY;
+ 
+   if (cif->abi != FFI_LINUX64)
+     {
++#ifndef __NO_FPRS__
+       /* Space for the FPR registers, if needed.  */
+       if (fparg_count != 0)
+ 	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
++#endif
+ 
+       /* Stack space.  */
+       if (intarg_count > NUM_GPR_ARG_REGISTERS)
+ 	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
++#ifndef __NO_FPRS__
+       if (fparg_count > NUM_FPR_ARG_REGISTERS)
+ 	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
++#endif
+     }
+   else
+     {
++#ifndef __NO_FPRS__
+       /* Space for the FPR registers, if needed.  */
+       if (fparg_count != 0)
+ 	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
++#endif
+ 
+       /* Stack space.  */
++#if _CALL_ELF == 2
++      if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0)
++	bytes += intarg_count * sizeof (long);
++#else
+       if (intarg_count > NUM_GPR_ARG_REGISTERS64)
+ 	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
++#endif
+     }
+ 
+   /* The stack space allocated needs to be a multiple of 16 bytes.  */
+   bytes = (bytes + 15) & ~0xF;
+ 
+   /* Add in the space for the copied structures.  */
+   bytes += struct_copy_size;
+ 
+   cif->flags = flags;
+   cif->bytes = bytes;
+ 
+   return FFI_OK;
+ }
+ 
++ffi_status
++ffi_prep_cif_machdep (ffi_cif *cif)
++{
++  cif->nfixedargs = cif->nargs;
++  return ffi_prep_cif_machdep_core (cif);
++}
++
++ffi_status
++ffi_prep_cif_machdep_var (ffi_cif *cif,
++			  unsigned int nfixedargs,
++			  unsigned int ntotalargs MAYBE_UNUSED)
++{
++  cif->nfixedargs = nfixedargs;
++#if _CALL_ELF == 2
++  if (cif->abi == FFI_LINUX64)
++    cif->flags |= FLAG_ARG_NEEDS_PSAVE;
++#endif
++  return ffi_prep_cif_machdep_core (cif);
++}
++
+ extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
+ 			  void (*fn)(void));
+ extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
+ 					unsigned long, unsigned long *,
+ 					void (*fn)(void));
+ 
+ void
+ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+ {
++  /*
++   * The final SYSV ABI says that structures smaller or equal 8 bytes
++   * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
++   * in memory.
++   *
++   * We bounce-buffer SYSV small struct return values so that sysv.S
++   * can write r3 and r4 to memory without worrying about struct size.
++   *
++   * For ELFv2 ABI, use a bounce buffer for homogeneous structs too,
++   * for similar reasons.
++   */
++  unsigned long smst_buffer[8];
+   extended_cif ecif;
+ 
+   ecif.cif = cif;
+   ecif.avalue = avalue;
+ 
+-  /* If the return value is a struct and we don't have a return	*/
+-  /* value address then we need to make one		        */
+-
+-  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
+-    {
+-      ecif.rvalue = alloca(cif->rtype->size);
+-    }
+-  else
+-    ecif.rvalue = rvalue;
+-
++  ecif.rvalue = rvalue;
++  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
++    ecif.rvalue = smst_buffer;
++  /* Ensure that we have a valid struct return value.
++     FIXME: Isn't this just papering over a user problem?  */
++  else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT)
++    ecif.rvalue = alloca (cif->rtype->size);
+ 
+   switch (cif->abi)
+     {
+ #ifndef POWERPC64
++# ifndef __NO_FPRS__
+     case FFI_SYSV:
+     case FFI_GCC_SYSV:
+     case FFI_LINUX:
++# endif
+     case FFI_LINUX_SOFT_FLOAT:
+       ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
+       break;
+ #else
+     case FFI_LINUX64:
+       ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
+       break;
+ #endif
+     default:
+       FFI_ASSERT (0);
+       break;
+     }
++
++  /* Check for a bounce-buffered return value */
++  if (rvalue && ecif.rvalue == smst_buffer)
++    {
++      unsigned int rsize = cif->rtype->size;
++#ifndef __LITTLE_ENDIAN__
++      /* The SYSV ABI returns a structure of up to 4 bytes in size
++	 left-padded in r3.  */
++      if (cif->abi == FFI_SYSV && rsize <= 4)
++	memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize);
++      /* The SYSV ABI returns a structure of up to 8 bytes in size
++	 left-padded in r3/r4, and the ELFv2 ABI similarly returns a
++	 structure of up to 8 bytes in size left-padded in r3.  */
++      else if (rsize <= 8)
++	memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
++      else
++#endif
++	memcpy (rvalue, smst_buffer, rsize);
++    }
+ }
+ 
+ 
+-#ifndef POWERPC64
++#if !defined POWERPC64 || _CALL_ELF == 2
+ #define MIN_CACHE_LINE_SIZE 8
+ 
+ static void
+ flush_icache (char *wraddr, char *xaddr, int size)
+ {
+   int i;
+   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
+     __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
+@@ -942,26 +1208,48 @@ flush_icache (char *wraddr, char *xaddr,
+ ffi_status
+ ffi_prep_closure_loc (ffi_closure *closure,
+ 		      ffi_cif *cif,
+ 		      void (*fun) (ffi_cif *, void *, void **, void *),
+ 		      void *user_data,
+ 		      void *codeloc)
+ {
+ #ifdef POWERPC64
++# if _CALL_ELF == 2
++  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
++
++  if (cif->abi != FFI_LINUX64)
++    return FFI_BAD_ABI;
++
++  tramp[0] = 0xe96c0018;	/* 0:	ld	11,2f-0b(12)	*/
++  tramp[1] = 0xe98c0010;	/*	ld	12,1f-0b(12)	*/
++  tramp[2] = 0x7d8903a6;	/*	mtctr	12		*/
++  tramp[3] = 0x4e800420;	/*	bctr			*/
++				/* 1:	.quad	function_addr	*/
++				/* 2:	.quad	context		*/
++  *(void **) &tramp[4] = (void *) ffi_closure_LINUX64;
++  *(void **) &tramp[6] = codeloc;
++  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
++# else
+   void **tramp = (void **) &closure->tramp[0];
+ 
+-  FFI_ASSERT (cif->abi == FFI_LINUX64);
++  if (cif->abi != FFI_LINUX64)
++    return FFI_BAD_ABI;
+   /* Copy function address and TOC from ffi_closure_LINUX64.  */
+   memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
+   tramp[2] = codeloc;
++# endif
+ #else
+   unsigned int *tramp;
+ 
+-  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
++  if (! (cif->abi == FFI_GCC_SYSV 
++	 || cif->abi == FFI_SYSV
++	 || cif->abi == FFI_LINUX
++	 || cif->abi == FFI_LINUX_SOFT_FLOAT))
++    return FFI_BAD_ABI;
+ 
+   tramp = (unsigned int *) &closure->tramp[0];
+   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
+   tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
+   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
+   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
+   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
+   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
+@@ -1006,110 +1294,215 @@ ffi_closure_helper_SYSV (ffi_closure *cl
+   /* rvalue is the pointer to space for return value in closure assembly */
+   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
+   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
+   /* pst is the pointer to outgoing parameter stack in original caller */
+ 
+   void **          avalue;
+   ffi_type **      arg_types;
+   long             i, avn;
+-  long             nf;   /* number of floating registers already used */
+-  long             ng;   /* number of general registers already used */
+-  ffi_cif *        cif;
+-  double           temp;
+-  unsigned         size;
++#ifndef __NO_FPRS__
++  long             nf = 0;   /* number of floating registers already used */
++#endif
++  long             ng = 0;   /* number of general registers already used */
+ 
+-  cif = closure->cif;
++  ffi_cif *cif = closure->cif;
++  unsigned       size     = cif->rtype->size;
++  unsigned short rtypenum = cif->rtype->type;
++
+   avalue = alloca (cif->nargs * sizeof (void *));
+-  size = cif->rtype->size;
+ 
+-  nf = 0;
+-  ng = 0;
++  /* First translate for softfloat/nonlinux */
++  if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
++	if (rtypenum == FFI_TYPE_FLOAT)
++		rtypenum = FFI_TYPE_UINT32;
++	if (rtypenum == FFI_TYPE_DOUBLE)
++		rtypenum = FFI_TYPE_UINT64;
++	if (rtypenum == FFI_TYPE_LONGDOUBLE)
++		rtypenum = FFI_TYPE_UINT128;
++  } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
++	if (rtypenum == FFI_TYPE_LONGDOUBLE)
++		rtypenum = FFI_TYPE_STRUCT;
++#endif
++  }
++
+ 
+   /* Copy the caller's structure return value address so that the closure
+      returns the data directly to the caller.
+      For FFI_SYSV the result is passed in r3/r4 if the struct size is less
+      or equal 8 bytes.  */
+-
+-  if ((cif->rtype->type == FFI_TYPE_STRUCT
+-       && !((cif->abi == FFI_SYSV) && (size <= 8)))
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
+-	  && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+-#endif
+-      )
+-    {
++  if (rtypenum == FFI_TYPE_STRUCT && ((cif->abi != FFI_SYSV) || (size > 8))) {
+       rvalue = (void *) *pgr;
+       ng++;
+       pgr++;
+     }
+ 
+   i = 0;
+   avn = cif->nargs;
+   arg_types = cif->arg_types;
+ 
+   /* Grab the addresses of the arguments from the stack frame.  */
+-  while (i < avn)
+-    {
+-      switch (arg_types[i]->type)
+-	{
++  while (i < avn) {
++      unsigned short typenum = arg_types[i]->type;
++
++      /* We may need to handle some values depending on ABI */
++      if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
++		if (typenum == FFI_TYPE_FLOAT)
++			typenum = FFI_TYPE_UINT32;
++		if (typenum == FFI_TYPE_DOUBLE)
++			typenum = FFI_TYPE_UINT64;
++		if (typenum == FFI_TYPE_LONGDOUBLE)
++			typenum = FFI_TYPE_UINT128;
++      } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
++		if (typenum == FFI_TYPE_LONGDOUBLE)
++			typenum = FFI_TYPE_STRUCT;
++#endif
++      }
++
++      switch (typenum) {
++#ifndef __NO_FPRS__
++	case FFI_TYPE_FLOAT:
++	  /* unfortunately float values are stored as doubles
++	   * in the ffi_closure_SYSV code (since we don't check
++	   * the type in that routine).
++	   */
++
++	  /* there are 8 64bit floating point registers */
++
++	  if (nf < 8)
++	    {
++	      double temp = pfr->d;
++	      pfr->f = (float) temp;
++	      avalue[i] = pfr;
++	      nf++;
++	      pfr++;
++	    }
++	  else
++	    {
++	      /* FIXME? here we are really changing the values
++	       * stored in the original calling routines outgoing
++	       * parameter stack.  This is probably a really
++	       * naughty thing to do but...
++	       */
++	      avalue[i] = pst;
++	      pst += 1;
++	    }
++	  break;
++
++	case FFI_TYPE_DOUBLE:
++	  /* On the outgoing stack all values are aligned to 8 */
++	  /* there are 8 64bit floating point registers */
++
++	  if (nf < 8)
++	    {
++	      avalue[i] = pfr;
++	      nf++;
++	      pfr++;
++	    }
++	  else
++	    {
++	      if (((long) pst) & 4)
++		pst++;
++	      avalue[i] = pst;
++	      pst += 2;
++	    }
++	  break;
++
++#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
++	case FFI_TYPE_LONGDOUBLE:
++	  if (nf < 7)
++	    {
++	      avalue[i] = pfr;
++	      pfr += 2;
++	      nf += 2;
++	    }
++	  else
++	    {
++	      if (((long) pst) & 4)
++		pst++;
++	      avalue[i] = pst;
++	      pst += 4;
++	      nf = 8;
++	    }
++	  break;
++#endif
++#endif /* have FPRS */
++
++	case FFI_TYPE_UINT128:
++		/*
++		 * Test if for the whole long double, 4 gprs are available.
++		 * otherwise the stuff ends up on the stack.
++		 */
++		if (ng < 5) {
++			avalue[i] = pgr;
++			pgr += 4;
++			ng += 4;
++		} else {
++			avalue[i] = pst;
++			pst += 4;
++			ng = 8+4;
++		}
++		break;
++
+ 	case FFI_TYPE_SINT8:
+ 	case FFI_TYPE_UINT8:
++#ifndef __LITTLE_ENDIAN__
+ 	  /* there are 8 gpr registers used to pass values */
+ 	  if (ng < 8)
+ 	    {
+ 	      avalue[i] = (char *) pgr + 3;
+ 	      ng++;
+ 	      pgr++;
+ 	    }
+ 	  else
+ 	    {
+ 	      avalue[i] = (char *) pst + 3;
+ 	      pst++;
+ 	    }
+ 	  break;
++#endif
+ 
+ 	case FFI_TYPE_SINT16:
+ 	case FFI_TYPE_UINT16:
++#ifndef __LITTLE_ENDIAN__
+ 	  /* there are 8 gpr registers used to pass values */
+ 	  if (ng < 8)
+ 	    {
+ 	      avalue[i] = (char *) pgr + 2;
+ 	      ng++;
+ 	      pgr++;
+ 	    }
+ 	  else
+ 	    {
+ 	      avalue[i] = (char *) pst + 2;
+ 	      pst++;
+ 	    }
+ 	  break;
++#endif
+ 
+ 	case FFI_TYPE_SINT32:
+ 	case FFI_TYPE_UINT32:
+ 	case FFI_TYPE_POINTER:
+-	soft_float_closure:
+ 	  /* there are 8 gpr registers used to pass values */
+ 	  if (ng < 8)
+ 	    {
+ 	      avalue[i] = pgr;
+ 	      ng++;
+ 	      pgr++;
+ 	    }
+ 	  else
+ 	    {
+ 	      avalue[i] = pst;
+ 	      pst++;
+ 	    }
+ 	  break;
+ 
+ 	case FFI_TYPE_STRUCT:
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-	do_struct:
+-#endif
+ 	  /* Structs are passed by reference. The address will appear in a
+ 	     gpr if it is one of the first 8 arguments.  */
+ 	  if (ng < 8)
+ 	    {
+ 	      avalue[i] = (void *) *pgr;
+ 	      ng++;
+ 	      pgr++;
+ 	    }
+@@ -1117,17 +1510,16 @@ ffi_closure_helper_SYSV (ffi_closure *cl
+ 	    {
+ 	      avalue[i] = (void *) *pst;
+ 	      pst++;
+ 	    }
+ 	  break;
+ 
+ 	case FFI_TYPE_SINT64:
+ 	case FFI_TYPE_UINT64:
+-	soft_double_closure:
+ 	  /* passing long long ints are complex, they must
+ 	   * be passed in suitable register pairs such as
+ 	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
+ 	   * and if the entire pair aren't available then the outgoing
+ 	   * parameter stack is used for both but an alignment of 8
+ 	   * must will be kept.  So we must either look in pgr
+ 	   * or pst to find the correct address for this type
+ 	   * of parameter.
+@@ -1149,277 +1541,239 @@ ffi_closure_helper_SYSV (ffi_closure *cl
+ 	      if (((long) pst) & 4)
+ 		pst++;
+ 	      avalue[i] = pst;
+ 	      pst += 2;
+ 	      ng = 8;
+ 	    }
+ 	  break;
+ 
+-	case FFI_TYPE_FLOAT:
+-	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
+-	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	    goto soft_float_closure;
+-	  /* unfortunately float values are stored as doubles
+-	   * in the ffi_closure_SYSV code (since we don't check
+-	   * the type in that routine).
+-	   */
+-
+-	  /* there are 8 64bit floating point registers */
+-
+-	  if (nf < 8)
+-	    {
+-	      temp = pfr->d;
+-	      pfr->f = (float) temp;
+-	      avalue[i] = pfr;
+-	      nf++;
+-	      pfr++;
+-	    }
+-	  else
+-	    {
+-	      /* FIXME? here we are really changing the values
+-	       * stored in the original calling routines outgoing
+-	       * parameter stack.  This is probably a really
+-	       * naughty thing to do but...
+-	       */
+-	      avalue[i] = pst;
+-	      pst += 1;
+-	    }
+-	  break;
+-
+-	case FFI_TYPE_DOUBLE:
+-	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
+-	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	    goto soft_double_closure;
+-	  /* On the outgoing stack all values are aligned to 8 */
+-	  /* there are 8 64bit floating point registers */
+-
+-	  if (nf < 8)
+-	    {
+-	      avalue[i] = pfr;
+-	      nf++;
+-	      pfr++;
+-	    }
+-	  else
+-	    {
+-	      if (((long) pst) & 4)
+-		pst++;
+-	      avalue[i] = pst;
+-	      pst += 2;
+-	    }
+-	  break;
+-
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-	case FFI_TYPE_LONGDOUBLE:
+-	  if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+-	    goto do_struct;
+-	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-	    { /* Test if for the whole long double, 4 gprs are available.
+-		 otherwise the stuff ends up on the stack.  */
+-	      if (ng < 5)
+-		{
+-		  avalue[i] = pgr;
+-		  pgr += 4;
+-		  ng += 4;
+-		}
+-	      else
+-		{
+-		  avalue[i] = pst;
+-		  pst += 4;
+-		  ng = 8;
+-		}
+-	      break;
+-	    }
+-	  if (nf < 7)
+-	    {
+-	      avalue[i] = pfr;
+-	      pfr += 2;
+-	      nf += 2;
+-	    }
+-	  else
+-	    {
+-	      if (((long) pst) & 4)
+-		pst++;
+-	      avalue[i] = pst;
+-	      pst += 4;
+-	      nf = 8;
+-	    }
+-	  break;
+-#endif
+-
+ 	default:
+-	  FFI_ASSERT (0);
++		FFI_ASSERT (0);
+ 	}
+ 
+       i++;
+     }
+ 
+ 
+   (closure->fun) (cif, rvalue, avalue, closure->user_data);
+ 
+   /* Tell ffi_closure_SYSV how to perform return type promotions.
+      Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
+      we have to tell ffi_closure_SYSV how to treat them. We combine the base
+      type FFI_SYSV_TYPE_SMALL_STRUCT - 1  with the size of the struct.
+      So a one byte struct gets the return type 16. Return type 1 to 15 are
+      already used and we never have a struct with size zero. That is the reason
+      for the subtraction of 1. See the comment in ffitarget.h about ordering.
+   */
+-  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
+-      && size <= 8)
++  if (cif->abi == FFI_SYSV && rtypenum == FFI_TYPE_STRUCT && size <= 8)
+     return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size;
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
+-	   && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
+-    return FFI_TYPE_STRUCT;
+-#endif
+-  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
+-     respectivley UINT64.  */
+-  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
+-    {
+-      switch (cif->rtype->type)
+-	{
+-	case FFI_TYPE_FLOAT:
+-	  return FFI_TYPE_UINT32;
+-	  break;
+-	case FFI_TYPE_DOUBLE:
+-	  return FFI_TYPE_UINT64;
+-	  break;
+-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+-	case FFI_TYPE_LONGDOUBLE:
+-	  return FFI_TYPE_UINT128;
+-	  break;
+-#endif
+-	default:
+-	  return cif->rtype->type;
+-	}
+-    }
+-  else
+-    {
+-      return cif->rtype->type;
+-    }
++  return rtypenum;
+ }
+ 
+ int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
+ 					   unsigned long *, ffi_dblfl *);
+ 
+ int FFI_HIDDEN
+ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
+ 			    unsigned long *pst, ffi_dblfl *pfr)
+ {
+   /* rvalue is the pointer to space for return value in closure assembly */
+   /* pst is the pointer to parameter save area
+      (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
+   /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
+ 
+   void **avalue;
+   ffi_type **arg_types;
+-  long i, avn;
++  unsigned long i, avn, nfixedargs;
+   ffi_cif *cif;
+   ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
++#ifdef __STRUCT_PARM_ALIGN__
++  unsigned long align;
++#endif
+ 
+   cif = closure->cif;
+   avalue = alloca (cif->nargs * sizeof (void *));
+ 
+-  /* Copy the caller's structure return value address so that the closure
+-     returns the data directly to the caller.  */
+-  if (cif->rtype->type == FFI_TYPE_STRUCT)
++  /* Copy the caller's structure return value address so that the
++     closure returns the data directly to the caller.  */
++  if (cif->rtype->type == FFI_TYPE_STRUCT
++      && (cif->flags & FLAG_RETURNS_SMST) == 0)
+     {
+       rvalue = (void *) *pst;
+       pst++;
+     }
+ 
+   i = 0;
+   avn = cif->nargs;
++  nfixedargs = cif->nfixedargs;
+   arg_types = cif->arg_types;
+ 
+   /* Grab the addresses of the arguments from the stack frame.  */
+   while (i < avn)
+     {
++      unsigned int elt, elnum;
++
+       switch (arg_types[i]->type)
+ 	{
+ 	case FFI_TYPE_SINT8:
+ 	case FFI_TYPE_UINT8:
++#ifndef __LITTLE_ENDIAN__
+ 	  avalue[i] = (char *) pst + 7;
+ 	  pst++;
+ 	  break;
++#endif
+ 
+ 	case FFI_TYPE_SINT16:
+ 	case FFI_TYPE_UINT16:
++#ifndef __LITTLE_ENDIAN__
+ 	  avalue[i] = (char *) pst + 6;
+ 	  pst++;
+ 	  break;
++#endif
+ 
+ 	case FFI_TYPE_SINT32:
+ 	case FFI_TYPE_UINT32:
++#ifndef __LITTLE_ENDIAN__
+ 	  avalue[i] = (char *) pst + 4;
+ 	  pst++;
+ 	  break;
++#endif
+ 
+ 	case FFI_TYPE_SINT64:
+ 	case FFI_TYPE_UINT64:
+ 	case FFI_TYPE_POINTER:
+ 	  avalue[i] = pst;
+ 	  pst++;
+ 	  break;
+ 
+ 	case FFI_TYPE_STRUCT:
+-	  /* Structures with size less than eight bytes are passed
+-	     left-padded.  */
+-	  if (arg_types[i]->size < 8)
+-	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
++#ifdef __STRUCT_PARM_ALIGN__
++	  align = arg_types[i]->alignment;
++	  if (align > __STRUCT_PARM_ALIGN__)
++	    align = __STRUCT_PARM_ALIGN__;
++	  if (align > 1)
++	    pst = (unsigned long *) ALIGN ((size_t) pst, align);
++#endif
++	  elt = 0;
++#if _CALL_ELF == 2
++	  elt = discover_homogeneous_aggregate (arg_types[i], &elnum);
++#endif
++	  if (elt)
++	    {
++	      union {
++		void *v;
++		unsigned long *ul;
++		float *f;
++		double *d;
++		size_t p;
++	      } to, from;
++
++	      /* Repackage the aggregate from its parts.  The
++		 aggregate size is not greater than the space taken by
++		 the registers so store back to the register/parameter
++		 save arrays.  */
++	      if (pfr + elnum <= end_pfr)
++		to.v = pfr;
++	      else
++		to.v = pst;
++
++	      avalue[i] = to.v;
++	      from.ul = pst;
++	      if (elt == FFI_TYPE_FLOAT)
++		{
++		  do
++		    {
++		      if (pfr < end_pfr && i < nfixedargs)
++			{
++			  *to.f = (float) pfr->d;
++			  pfr++;
++			}
++		      else
++			*to.f = *from.f;
++		      to.f++;
++		      from.f++;
++		    }
++		  while (--elnum != 0);
++		}
++	      else
++		{
++		  do
++		    {
++		      if (pfr < end_pfr && i < nfixedargs)
++			{
++			  *to.d = pfr->d;
++			  pfr++;
++			}
++		      else
++			*to.d = *from.d;
++		      to.d++;
++		      from.d++;
++		    }
++		  while (--elnum != 0);
++		}
++	    }
+ 	  else
+-	    avalue[i] = pst;
++	    {
++#ifndef __LITTLE_ENDIAN__
++	      /* Structures with size less than eight bytes are passed
++		 left-padded.  */
++	      if (arg_types[i]->size < 8)
++		avalue[i] = (char *) pst + 8 - arg_types[i]->size;
++	      else
++#endif
++		avalue[i] = pst;
++	    }
+ 	  pst += (arg_types[i]->size + 7) / 8;
+ 	  break;
+ 
+ 	case FFI_TYPE_FLOAT:
+ 	  /* unfortunately float values are stored as doubles
+ 	   * in the ffi_closure_LINUX64 code (since we don't check
+ 	   * the type in that routine).
+ 	   */
+ 
+ 	  /* there are 13 64bit floating point registers */
+ 
+-	  if (pfr < end_pfr)
++	  if (pfr < end_pfr && i < nfixedargs)
+ 	    {
+ 	      double temp = pfr->d;
+ 	      pfr->f = (float) temp;
+ 	      avalue[i] = pfr;
+ 	      pfr++;
+ 	    }
+ 	  else
+ 	    avalue[i] = pst;
+ 	  pst++;
+ 	  break;
+ 
+ 	case FFI_TYPE_DOUBLE:
+ 	  /* On the outgoing stack all values are aligned to 8 */
+ 	  /* there are 13 64bit floating point registers */
+ 
+-	  if (pfr < end_pfr)
++	  if (pfr < end_pfr && i < nfixedargs)
+ 	    {
+ 	      avalue[i] = pfr;
+ 	      pfr++;
+ 	    }
+ 	  else
+ 	    avalue[i] = pst;
+ 	  pst++;
+ 	  break;
+ 
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ 	case FFI_TYPE_LONGDOUBLE:
+-	  if (pfr + 1 < end_pfr)
++	  if (pfr + 1 < end_pfr && i + 1 < nfixedargs)
+ 	    {
+ 	      avalue[i] = pfr;
+ 	      pfr += 2;
+ 	    }
+ 	  else
+ 	    {
+-	      if (pfr < end_pfr)
++	      if (pfr < end_pfr && i < nfixedargs)
+ 		{
+ 		  /* Passed partly in f13 and partly on the stack.
+ 		     Move it all to the stack.  */
+ 		  *pst = *(unsigned long *) pfr;
+ 		  pfr++;
+ 		}
+ 	      avalue[i] = pst;
+ 	    }
+@@ -1433,10 +1787,19 @@ ffi_closure_helper_LINUX64 (ffi_closure 
+ 
+       i++;
+     }
+ 
+ 
+   (closure->fun) (cif, rvalue, avalue, closure->user_data);
+ 
+   /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
++  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
++    {
++      if ((cif->flags & FLAG_RETURNS_FP) == 0)
++	return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1;
++      else if ((cif->flags & FLAG_RETURNS_64BITS) != 0)
++	return FFI_V2_TYPE_DOUBLE_HOMOG;
++      else
++	return FFI_V2_TYPE_FLOAT_HOMOG;
++    }
+   return cif->rtype->type;
+ }
+diff --git a/js/src/ctypes/libffi/src/powerpc/ffitarget.h b/js/src/ctypes/libffi/src/powerpc/ffitarget.h
+--- a/js/src/ctypes/libffi/src/powerpc/ffitarget.h
++++ b/js/src/ctypes/libffi/src/powerpc/ffitarget.h
+@@ -1,11 +1,13 @@
+ /* -----------------------------------------------------------------*-C-*-
+-   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
+-   Copyright (C) 2007, 2008 Free Software Foundation, Inc
++   ffitarget.h - Copyright (c) 2012  Anthony Green
++                 Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
++                 Copyright (c) 1996-2003  Red Hat, Inc.
++
+    Target configuration macros for PowerPC.
+ 
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    ``Software''), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+@@ -23,16 +25,20 @@
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+    DEALINGS IN THE SOFTWARE.
+ 
+    ----------------------------------------------------------------------- */
+ 
+ #ifndef LIBFFI_TARGET_H
+ #define LIBFFI_TARGET_H
+ 
++#ifndef LIBFFI_H
++#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
++#endif
++
+ /* ---- System specific configurations ----------------------------------- */
+ 
+ #if defined (POWERPC) && defined (__powerpc64__)	/* linux64 */
+ #ifndef POWERPC64
+ #define POWERPC64
+ #endif
+ #elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin */
+ #ifndef POWERPC64
+@@ -52,28 +58,24 @@ typedef enum ffi_abi {
+   FFI_FIRST_ABI = 0,
+ 
+ #ifdef POWERPC
+   FFI_SYSV,
+   FFI_GCC_SYSV,
+   FFI_LINUX64,
+   FFI_LINUX,
+   FFI_LINUX_SOFT_FLOAT,
+-# ifdef POWERPC64
++# if defined(POWERPC64)
+   FFI_DEFAULT_ABI = FFI_LINUX64,
++# elif defined(__NO_FPRS__)
++  FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
++# elif (__LDBL_MANT_DIG__ == 106)
++  FFI_DEFAULT_ABI = FFI_LINUX,
+ # else
+-#  if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
+-  FFI_DEFAULT_ABI = FFI_LINUX,
+-#  else
+-#   ifdef __NO_FPRS__
+-  FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
+-#   else
+   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
+-#   endif
+-#  endif
+ # endif
+ #endif
+ 
+ #ifdef POWERPC_AIX
+   FFI_AIX,
+   FFI_DARWIN,
+   FFI_DEFAULT_ABI = FFI_AIX,
+ #endif
+@@ -96,32 +98,45 @@ typedef enum ffi_abi {
+   FFI_LAST_ABI
+ } ffi_abi;
+ #endif
+ 
+ /* ---- Definitions for closures ----------------------------------------- */
+ 
+ #define FFI_CLOSURES 1
+ #define FFI_NATIVE_RAW_API 0
++#if defined (POWERPC) || defined (POWERPC_FREEBSD)
++# define FFI_TARGET_SPECIFIC_VARIADIC 1
++# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
++#endif
+ 
+ /* For additional types like the below, take care about the order in
+    ppc_closures.S. They must follow after the FFI_TYPE_LAST.  */
+ 
+ /* Needed for soft-float long-double-128 support.  */
+ #define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
+ 
+ /* Needed for FFI_SYSV small structure returns.
+    We use two flag bits, (FLAG_SYSV_SMST_R3, FLAG_SYSV_SMST_R4) which are
+    defined in ffi.c, to determine the exact return type and its size.  */
+ #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
+ 
+-#if defined(POWERPC64) || defined(POWERPC_AIX)
+-#define FFI_TRAMPOLINE_SIZE 24
+-#else /* POWERPC || POWERPC_AIX */
+-#define FFI_TRAMPOLINE_SIZE 40
++/* Used by ELFv2 for homogenous structure returns.  */
++#define FFI_V2_TYPE_FLOAT_HOMOG		(FFI_TYPE_LAST + 1)
++#define FFI_V2_TYPE_DOUBLE_HOMOG	(FFI_TYPE_LAST + 2)
++#define FFI_V2_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 3)
++
++#if _CALL_ELF == 2
++# define FFI_TRAMPOLINE_SIZE 32
++#else
++# if defined(POWERPC64) || defined(POWERPC_AIX)
++#  define FFI_TRAMPOLINE_SIZE 24
++# else /* POWERPC || POWERPC_AIX */
++#  define FFI_TRAMPOLINE_SIZE 40
++# endif
+ #endif
+ 
+ #ifndef LIBFFI_ASM
+ #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
+ struct ffi_aix_trampoline_struct {
+     void * code_pointer;	/* Pointer to ffi_closure_ASM */
+     void * toc;			/* TOC */
+     void * static_chain;	/* Pointer to closure */
+diff --git a/js/src/ctypes/libffi/src/powerpc/linux64.S b/js/src/ctypes/libffi/src/powerpc/linux64.S
+--- a/js/src/ctypes/libffi/src/powerpc/linux64.S
++++ b/js/src/ctypes/libffi/src/powerpc/linux64.S
+@@ -25,56 +25,86 @@
+    DEALINGS IN THE SOFTWARE.
+    ----------------------------------------------------------------------- */
+ 
+ #define LIBFFI_ASM
+ #include <fficonfig.h>
+ #include <ffi.h>
+ 
+ #ifdef __powerpc64__
+-	.hidden	ffi_call_LINUX64, .ffi_call_LINUX64
+-	.globl	ffi_call_LINUX64, .ffi_call_LINUX64
++	.hidden	ffi_call_LINUX64
++	.globl	ffi_call_LINUX64
++# if _CALL_ELF == 2
++	.text
++ffi_call_LINUX64:
++	addis	%r2, %r12, .TOC.-ffi_call_LINUX64@ha
++	addi	%r2, %r2, .TOC.-ffi_call_LINUX64@l
++	.localentry ffi_call_LINUX64, . - ffi_call_LINUX64
++# else
+ 	.section	".opd","aw"
+ 	.align	3
+ ffi_call_LINUX64:
++#  ifdef _CALL_LINUX
++	.quad	.L.ffi_call_LINUX64,.TOC.@tocbase,0
++	.type	ffi_call_LINUX64,@function
++	.text
++.L.ffi_call_LINUX64:
++#  else
++	.hidden	.ffi_call_LINUX64
++	.globl	.ffi_call_LINUX64
+ 	.quad	.ffi_call_LINUX64,.TOC.@tocbase,0
+ 	.size	ffi_call_LINUX64,24
+ 	.type	.ffi_call_LINUX64,@function
+ 	.text
+ .ffi_call_LINUX64:
++#  endif
++# endif
+ .LFB1:
+ 	mflr	%r0
+ 	std	%r28, -32(%r1)
+ 	std	%r29, -24(%r1)
+ 	std	%r30, -16(%r1)
+ 	std	%r31, -8(%r1)
+ 	std	%r0, 16(%r1)
+ 
+ 	mr	%r28, %r1	/* our AP.  */
+ .LCFI0:
+ 	stdux	%r1, %r1, %r4
+ 	mr	%r31, %r5	/* flags, */
+ 	mr	%r30, %r6	/* rvalue, */
+ 	mr	%r29, %r7	/* function address.  */
++/* Save toc pointer, not for the ffi_prep_args64 call, but for the later
++   bctrl function call.  */
++# if _CALL_ELF == 2
++	std	%r2, 24(%r1)
++# else
+ 	std	%r2, 40(%r1)
++# endif
+ 
+ 	/* Call ffi_prep_args64.  */
+ 	mr	%r4, %r1
++# if defined _CALL_LINUX || _CALL_ELF == 2
++	bl	ffi_prep_args64
++# else
+ 	bl	.ffi_prep_args64
++# endif
+ 
+-	ld	%r0, 0(%r29)
++# if _CALL_ELF == 2
++	mr	%r12, %r29
++# else
++	ld	%r12, 0(%r29)
+ 	ld	%r2, 8(%r29)
+ 	ld	%r11, 16(%r29)
+-
++# endif
+ 	/* Now do the call.  */
+ 	/* Set up cr1 with bits 4-7 of the flags.  */
+ 	mtcrf	0x40, %r31
+ 
+ 	/* Get the address to call into CTR.  */
+-	mtctr	%r0
++	mtctr	%r12
+ 	/* Load all those argument registers.  */
+ 	ld	%r3, -32-(8*8)(%r28)
+ 	ld	%r4, -32-(7*8)(%r28)
+ 	ld	%r5, -32-(6*8)(%r28)
+ 	ld	%r6, -32-(5*8)(%r28)
+ 	bf-	5, 1f
+ 	ld	%r7, -32-(4*8)(%r28)
+ 	ld	%r8, -32-(3*8)(%r28)
+@@ -99,50 +129,93 @@ 1:
+ 	lfd	%f13, -32-(9*8)(%r28)
+ 2:
+ 
+ 	/* Make the call.  */
+ 	bctrl
+ 
+ 	/* This must follow the call immediately, the unwinder
+ 	   uses this to find out if r2 has been saved or not.  */
++# if _CALL_ELF == 2
++	ld	%r2, 24(%r1)
++# else
+ 	ld	%r2, 40(%r1)
++# endif
+ 
+ 	/* Now, deal with the return value.  */
+ 	mtcrf	0x01, %r31
+-	bt-	30, .Ldone_return_value
+-	bt-	29, .Lfp_return_value
++	bt	31, .Lstruct_return_value
++	bt	30, .Ldone_return_value
++	bt	29, .Lfp_return_value
+ 	std	%r3, 0(%r30)
+ 	/* Fall through...  */
+ 
+ .Ldone_return_value:
+ 	/* Restore the registers we used and return.  */
+ 	mr	%r1, %r28
+ 	ld	%r0, 16(%r28)
+-	ld	%r28, -32(%r1)
++	ld	%r28, -32(%r28)
+ 	mtlr	%r0
+ 	ld	%r29, -24(%r1)
+ 	ld	%r30, -16(%r1)
+ 	ld	%r31, -8(%r1)
+ 	blr
+ 
+ .Lfp_return_value:
+ 	bf	28, .Lfloat_return_value
+ 	stfd	%f1, 0(%r30)
+ 	mtcrf	0x02, %r31 /* cr6  */
+ 	bf	27, .Ldone_return_value
+ 	stfd	%f2, 8(%r30)
+ 	b	.Ldone_return_value
+ .Lfloat_return_value:
+ 	stfs	%f1, 0(%r30)
+ 	b	.Ldone_return_value
++
++.Lstruct_return_value:
++	bf	29, .Lsmall_struct
++	bf	28, .Lfloat_homog_return_value
++	stfd	%f1, 0(%r30)
++	stfd	%f2, 8(%r30)
++	stfd	%f3, 16(%r30)
++	stfd	%f4, 24(%r30)
++	stfd	%f5, 32(%r30)
++	stfd	%f6, 40(%r30)
++	stfd	%f7, 48(%r30)
++	stfd	%f8, 56(%r30)
++	b	.Ldone_return_value
++
++.Lfloat_homog_return_value:
++	stfs	%f1, 0(%r30)
++	stfs	%f2, 4(%r30)
++	stfs	%f3, 8(%r30)
++	stfs	%f4, 12(%r30)
++	stfs	%f5, 16(%r30)
++	stfs	%f6, 20(%r30)
++	stfs	%f7, 24(%r30)
++	stfs	%f8, 28(%r30)
++	b	.Ldone_return_value
++
++.Lsmall_struct:
++	std	%r3, 0(%r30)
++	std	%r4, 8(%r30)
++	b	.Ldone_return_value
++
+ .LFE1:
+ 	.long	0
+ 	.byte	0,12,0,1,128,4,0,0
++# if _CALL_ELF == 2
++	.size	ffi_call_LINUX64,.-ffi_call_LINUX64
++# else
++#  ifdef _CALL_LINUX
++	.size	ffi_call_LINUX64,.-.L.ffi_call_LINUX64
++#  else
+ 	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64
++#  endif
++# endif
+ 
+ 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
+ .Lframe1:
+ 	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+ .LSCIE1:
+ 	.4byte	0x0	 # CIE Identifier Tag
+ 	.byte	0x1	 # CIE Version
+ 	.ascii "zR\0"	 # CIE Augmentation
+@@ -175,13 +248,13 @@ 2:
+ 	.byte	0x9e	 # DW_CFA_offset, column 0x1e
+ 	.uleb128 0x2
+ 	.byte	0x9d	 # DW_CFA_offset, column 0x1d
+ 	.uleb128 0x3
+ 	.byte	0x9c	 # DW_CFA_offset, column 0x1c
+ 	.uleb128 0x4
+ 	.align 3
+ .LEFDE1:
++
++# if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
++	.section	.note.GNU-stack,"",@progbits
++# endif
+ #endif
+-
+-#if defined __ELF__ && defined __linux__
+-	.section	.note.GNU-stack,"",@progbits
+-#endif
+diff --git a/js/src/ctypes/libffi/src/powerpc/linux64_closure.S b/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
+--- a/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
++++ b/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
+@@ -27,179 +27,330 @@
+ #define LIBFFI_ASM
+ #include <fficonfig.h>
+ #include <ffi.h>
+ 
+ 	.file	"linux64_closure.S"
+ 
+ #ifdef __powerpc64__
+ 	FFI_HIDDEN (ffi_closure_LINUX64)
+-	FFI_HIDDEN (.ffi_closure_LINUX64)
+-	.globl  ffi_closure_LINUX64, .ffi_closure_LINUX64
++	.globl  ffi_closure_LINUX64
++# if _CALL_ELF == 2
++	.text
++ffi_closure_LINUX64:
++	addis	%r2, %r12, .TOC.-ffi_closure_LINUX64@ha
++	addi	%r2, %r2, .TOC.-ffi_closure_LINUX64@l
++	.localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64
++# else
+ 	.section        ".opd","aw"
+ 	.align  3
+ ffi_closure_LINUX64:
++#  ifdef _CALL_LINUX
++	.quad   .L.ffi_closure_LINUX64,.TOC.@tocbase,0
++	.type   ffi_closure_LINUX64,@function
++	.text
++.L.ffi_closure_LINUX64:
++#  else
++	FFI_HIDDEN (.ffi_closure_LINUX64)
++	.globl  .ffi_closure_LINUX64
+ 	.quad   .ffi_closure_LINUX64,.TOC.@tocbase,0
+ 	.size   ffi_closure_LINUX64,24
+ 	.type   .ffi_closure_LINUX64,@function
+ 	.text
+ .ffi_closure_LINUX64:
++#  endif
++# endif
++
++# if _CALL_ELF == 2
++#  32 byte special reg save area + 64 byte parm save area
++#  + 64 byte retval area + 13*8 fpr save area + round to 16
++#  define STACKFRAME 272
++#  define PARMSAVE 32
++#  define RETVAL PARMSAVE+64
++# else
++#  48 bytes special reg save area + 64 bytes parm save area
++#  + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
++#  define STACKFRAME 240
++#  define PARMSAVE 48
++#  define RETVAL PARMSAVE+64
++# endif
++
+ .LFB1:
+-	# save general regs into parm save area
+-	std	%r3, 48(%r1)
+-	std	%r4, 56(%r1)
+-	std	%r5, 64(%r1)
+-	std	%r6, 72(%r1)
++# if _CALL_ELF == 2
++	ld	%r12, FFI_TRAMPOLINE_SIZE(%r11)		# closure->cif
+ 	mflr	%r0
++	lwz	%r12, 28(%r12)				# cif->flags
++	mtcrf	0x40, %r12
++	addi	%r12, %r1, PARMSAVE
++	bt	7, .Lparmsave
++	# Our caller has not allocated a parameter save area.
++	# We need to allocate one here and use it to pass gprs to
++	# ffi_closure_helper_LINUX64.
++	addi	%r12, %r1, -STACKFRAME+PARMSAVE
++.Lparmsave:
++	std	%r0, 16(%r1)
++	# Save general regs into parm save area
++	std	%r3, 0(%r12)
++	std	%r4, 8(%r12)
++	std	%r5, 16(%r12)
++	std	%r6, 24(%r12)
++	std	%r7, 32(%r12)
++	std	%r8, 40(%r12)
++	std	%r9, 48(%r12)
++	std	%r10, 56(%r12)
+ 
+-	std	%r7, 80(%r1)
+-	std	%r8, 88(%r1)
+-	std	%r9, 96(%r1)
+-	std	%r10, 104(%r1)
++	# load up the pointer to the parm save area
++	mr	%r5, %r12
++# else
++	mflr	%r0
++	# Save general regs into parm save area
++	# This is the parameter save area set up by our caller.
++	std	%r3, PARMSAVE+0(%r1)
++	std	%r4, PARMSAVE+8(%r1)
++	std	%r5, PARMSAVE+16(%r1)
++	std	%r6, PARMSAVE+24(%r1)
++	std	%r7, PARMSAVE+32(%r1)
++	std	%r8, PARMSAVE+40(%r1)
++	std	%r9, PARMSAVE+48(%r1)
++	std	%r10, PARMSAVE+56(%r1)
++
+ 	std	%r0, 16(%r1)
+ 
+-	# mandatory 48 bytes special reg save area + 64 bytes parm save area
+-	# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
+-	stdu	%r1, -240(%r1)
++	# load up the pointer to the parm save area
++	addi	%r5, %r1, PARMSAVE
++# endif
++
++	# next save fpr 1 to fpr 13
++	stfd	%f1, -104+(0*8)(%r1)
++	stfd	%f2, -104+(1*8)(%r1)
++	stfd	%f3, -104+(2*8)(%r1)
++	stfd	%f4, -104+(3*8)(%r1)
++	stfd	%f5, -104+(4*8)(%r1)
++	stfd	%f6, -104+(5*8)(%r1)
++	stfd	%f7, -104+(6*8)(%r1)
++	stfd	%f8, -104+(7*8)(%r1)
++	stfd	%f9, -104+(8*8)(%r1)
++	stfd	%f10, -104+(9*8)(%r1)
++	stfd	%f11, -104+(10*8)(%r1)
++	stfd	%f12, -104+(11*8)(%r1)
++	stfd	%f13, -104+(12*8)(%r1)
++
++	# load up the pointer to the saved fpr registers */
++	addi	%r6, %r1, -104
++
++	# load up the pointer to the result storage
++	addi	%r4, %r1, -STACKFRAME+RETVAL
++
++	stdu	%r1, -STACKFRAME(%r1)
+ .LCFI0:
+ 
+-	# next save fpr 1 to fpr 13
+-	stfd  %f1, 128+(0*8)(%r1)
+-	stfd  %f2, 128+(1*8)(%r1)
+-	stfd  %f3, 128+(2*8)(%r1)
+-	stfd  %f4, 128+(3*8)(%r1)
+-	stfd  %f5, 128+(4*8)(%r1)
+-	stfd  %f6, 128+(5*8)(%r1)
+-	stfd  %f7, 128+(6*8)(%r1)
+-	stfd  %f8, 128+(7*8)(%r1)
+-	stfd  %f9, 128+(8*8)(%r1)
+-	stfd  %f10, 128+(9*8)(%r1)
+-	stfd  %f11, 128+(10*8)(%r1)
+-	stfd  %f12, 128+(11*8)(%r1)
+-	stfd  %f13, 128+(12*8)(%r1)
+-
+-	# set up registers for the routine that actually does the work
+ 	# get the context pointer from the trampoline
+-	mr %r3, %r11
+-
+-	# now load up the pointer to the result storage
+-	addi %r4, %r1, 112
+-
+-	# now load up the pointer to the parameter save area
+-	# in the previous frame
+-	addi %r5, %r1, 240 + 48
+-
+-	# now load up the pointer to the saved fpr registers */
+-	addi %r6, %r1, 128
++	mr	%r3, %r11
+ 
+ 	# make the call
++# if defined _CALL_LINUX || _CALL_ELF == 2
++	bl ffi_closure_helper_LINUX64
++# else
+ 	bl .ffi_closure_helper_LINUX64
++# endif
+ .Lret:
+ 
+ 	# now r3 contains the return type
+ 	# so use it to look up in a table
+ 	# so we know how to deal with each type
+ 
+ 	# look up the proper starting point in table
+ 	# by using return type as offset
++	ld %r0, STACKFRAME+16(%r1)
++	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT
++	bge .Lsmall
+ 	mflr %r4		# move address of .Lret to r4
+ 	sldi %r3, %r3, 4	# now multiply return type by 16
+ 	addi %r4, %r4, .Lret_type0 - .Lret
+-	ld %r0, 240+16(%r1)
+ 	add %r3, %r3, %r4	# add contents of table to table address
+ 	mtctr %r3
+ 	bctr			# jump to it
+ 
+ # Each of the ret_typeX code fragments has to be exactly 16 bytes long
+ # (4 instructions). For cache effectiveness we align to a 16 byte boundary
+ # first.
+ 	.align 4
+ 
+ .Lret_type0:
+ # case FFI_TYPE_VOID
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ 	nop
+ # case FFI_TYPE_INT
+-	lwa %r3, 112+4(%r1)
++# ifdef __LITTLE_ENDIAN__
++	lwa %r3, RETVAL+0(%r1)
++# else
++	lwa %r3, RETVAL+4(%r1)
++# endif
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_FLOAT
+-	lfs %f1, 112+0(%r1)
++	lfs %f1, RETVAL+0(%r1)
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_DOUBLE
+-	lfd %f1, 112+0(%r1)
++	lfd %f1, RETVAL+0(%r1)
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_LONGDOUBLE
+-	lfd %f1, 112+0(%r1)
++	lfd %f1, RETVAL+0(%r1)
+ 	mtlr %r0
+-	lfd %f2, 112+8(%r1)
++	lfd %f2, RETVAL+8(%r1)
+ 	b .Lfinish
+ # case FFI_TYPE_UINT8
+-	lbz %r3, 112+7(%r1)
++# ifdef __LITTLE_ENDIAN__
++	lbz %r3, RETVAL+0(%r1)
++# else
++	lbz %r3, RETVAL+7(%r1)
++# endif
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_SINT8
+-	lbz %r3, 112+7(%r1)
++# ifdef __LITTLE_ENDIAN__
++	lbz %r3, RETVAL+0(%r1)
++# else
++	lbz %r3, RETVAL+7(%r1)
++# endif
+ 	extsb %r3,%r3
+ 	mtlr %r0
+ 	b .Lfinish
+ # case FFI_TYPE_UINT16
+-	lhz %r3, 112+6(%r1)
++# ifdef __LITTLE_ENDIAN__
++	lhz %r3, RETVAL+0(%r1)
++# else
++	lhz %r3, RETVAL+6(%r1)
++# endif
+ 	mtlr %r0
+ .Lfinish:
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_SINT16
+-	lha %r3, 112+6(%r1)
++# ifdef __LITTLE_ENDIAN__
++	lha %r3, RETVAL+0(%r1)
++# else
++	lha %r3, RETVAL+6(%r1)
++# endif
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_UINT32
+-	lwz %r3, 112+4(%r1)
++# ifdef __LITTLE_ENDIAN__
++	lwz %r3, RETVAL+0(%r1)
++# else
++	lwz %r3, RETVAL+4(%r1)
++# endif
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_SINT32
+-	lwa %r3, 112+4(%r1)
++# ifdef __LITTLE_ENDIAN__
++	lwa %r3, RETVAL+0(%r1)
++# else
++	lwa %r3, RETVAL+4(%r1)
++# endif
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_UINT64
+-	ld %r3, 112+0(%r1)
++	ld %r3, RETVAL+0(%r1)
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_SINT64
+-	ld %r3, 112+0(%r1)
++	ld %r3, RETVAL+0(%r1)
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ # case FFI_TYPE_STRUCT
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+ 	nop
+ # case FFI_TYPE_POINTER
+-	ld %r3, 112+0(%r1)
++	ld %r3, RETVAL+0(%r1)
+ 	mtlr %r0
+-	addi %r1, %r1, 240
++	addi %r1, %r1, STACKFRAME
+ 	blr
+-# esac
++# case FFI_V2_TYPE_FLOAT_HOMOG
++	lfs %f1, RETVAL+0(%r1)
++	lfs %f2, RETVAL+4(%r1)
++	lfs %f3, RETVAL+8(%r1)
++	b .Lmorefloat
++# case FFI_V2_TYPE_DOUBLE_HOMOG
++	lfd %f1, RETVAL+0(%r1)
++	lfd %f2, RETVAL+8(%r1)
++	lfd %f3, RETVAL+16(%r1)
++	lfd %f4, RETVAL+24(%r1)
++	mtlr %r0
++	lfd %f5, RETVAL+32(%r1)
++	lfd %f6, RETVAL+40(%r1)
++	lfd %f7, RETVAL+48(%r1)
++	lfd %f8, RETVAL+56(%r1)
++	addi %r1, %r1, STACKFRAME
++	blr
++.Lmorefloat:
++	lfs %f4, RETVAL+12(%r1)
++	mtlr %r0
++	lfs %f5, RETVAL+16(%r1)
++	lfs %f6, RETVAL+20(%r1)
++	lfs %f7, RETVAL+24(%r1)
++	lfs %f8, RETVAL+28(%r1)
++	addi %r1, %r1, STACKFRAME
++	blr
++.Lsmall:
++# ifdef __LITTLE_ENDIAN__
++	ld %r3,RETVAL+0(%r1)
++	mtlr %r0
++	ld %r4,RETVAL+8(%r1)
++	addi %r1, %r1, STACKFRAME
++	blr
++# else
++	# A struct smaller than a dword is returned in the low bits of r3
++	# ie. right justified.  Larger structs are passed left justified
++	# in r3 and r4.  The return value area on the stack will have
++	# the structs as they are usually stored in memory.
++	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes?
++	neg %r5, %r3
++	ld %r3,RETVAL+0(%r1)
++	blt .Lsmalldown
++	mtlr %r0
++	ld %r4,RETVAL+8(%r1)
++	addi %r1, %r1, STACKFRAME
++	blr
++.Lsmalldown:
++	addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
++	mtlr %r0
++	sldi %r5, %r5, 3
++	addi %r1, %r1, STACKFRAME
++	srd %r3, %r3, %r5
++	blr
++# endif
++
+ .LFE1:
+ 	.long	0
+ 	.byte	0,12,0,1,128,0,0,0
++# if _CALL_ELF == 2
++	.size	ffi_closure_LINUX64,.-ffi_closure_LINUX64
++# else
++#  ifdef _CALL_LINUX
++	.size	ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
++#  else
+ 	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
++#  endif
++# endif
+ 
+ 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
+ .Lframe1:
+ 	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
+ .LSCIE1:
+ 	.4byte	0x0	 # CIE Identifier Tag
+ 	.byte	0x1	 # CIE Version
+ 	.ascii "zR\0"	 # CIE Augmentation
+@@ -218,19 +369,19 @@ ffi_closure_LINUX64:
+ .LASFDE1:
+ 	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
+ 	.8byte	.LFB1-.	 # FDE initial location
+ 	.8byte	.LFE1-.LFB1	 # FDE address range
+ 	.uleb128 0x0	 # Augmentation size
+ 	.byte	0x2	 # DW_CFA_advance_loc1
+ 	.byte	.LCFI0-.LFB1
+ 	.byte	0xe	 # DW_CFA_def_cfa_offset
+-	.uleb128 240
++	.uleb128 STACKFRAME
+ 	.byte	0x11	 # DW_CFA_offset_extended_sf
+ 	.uleb128 0x41
+ 	.sleb128 -2
+ 	.align 3
+ .LEFDE1:
++
++# if defined __ELF__ && defined __linux__
++	.section	.note.GNU-stack,"",@progbits
++# endif
+ #endif
+-
+-#if defined __ELF__ && defined __linux__
+-	.section	.note.GNU-stack,"",@progbits
+-#endif
+diff --git a/js/src/ctypes/libffi/src/powerpc/ppc_closure.S b/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
+--- a/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
++++ b/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
+@@ -117,53 +117,88 @@ ENTRY(ffi_closure_SYSV)
+ # case FFI_TYPE_INT
+ 	lwz %r3,112+0(%r1)
+ 	mtlr %r0
+ .Lfinish:
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_TYPE_FLOAT
++#ifndef __NO_FPRS__
+ 	lfs %f1,112+0(%r1)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
++#else
++	nop
++	nop
++	nop
++#endif
+ 	blr
+ 
+ # case FFI_TYPE_DOUBLE
++#ifndef __NO_FPRS__
+ 	lfd %f1,112+0(%r1)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
++#else
++	nop
++	nop
++	nop
++#endif
+ 	blr
+ 
+ # case FFI_TYPE_LONGDOUBLE
++#ifndef __NO_FPRS__
+ 	lfd %f1,112+0(%r1)
+ 	lfd %f2,112+8(%r1)
+ 	mtlr %r0
+ 	b .Lfinish
++#else
++	nop
++	nop
++	nop
++	blr
++#endif
+ 
+ # case FFI_TYPE_UINT8
++#ifdef __LITTLE_ENDIAN__
++	lbz %r3,112+0(%r1)
++#else
+ 	lbz %r3,112+3(%r1)
++#endif
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_TYPE_SINT8
++#ifdef __LITTLE_ENDIAN__
++	lbz %r3,112+0(%r1)
++#else
+ 	lbz %r3,112+3(%r1)
++#endif
+ 	extsb %r3,%r3
+ 	mtlr %r0
+ 	b .Lfinish
+ 
+ # case FFI_TYPE_UINT16
++#ifdef __LITTLE_ENDIAN__
++	lhz %r3,112+0(%r1)
++#else
+ 	lhz %r3,112+2(%r1)
++#endif
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_TYPE_SINT16
++#ifdef __LITTLE_ENDIAN__
++	lha %r3,112+0(%r1)
++#else
+ 	lha %r3,112+2(%r1)
++#endif
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_TYPE_UINT32
+ 	lwz %r3,112+0(%r1)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+@@ -198,76 +233,99 @@ ENTRY(ffi_closure_SYSV)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_TYPE_UINT128
+ 	lwz %r3,112+0(%r1)
+ 	lwz %r4,112+4(%r1)
+ 	lwz %r5,112+8(%r1)
+-	bl .Luint128
++	b .Luint128
+ 
+ # The return types below are only used when the ABI type is FFI_SYSV.
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
+ 	lbz %r3,112+0(%r1)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
+ 	lhz %r3,112+0(%r1)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
+ 	lwz %r3,112+0(%r1)
++#ifdef __LITTLE_ENDIAN__
++	mtlr %r0
++	addi %r1,%r1,144
++	blr
++#else
+ 	srwi %r3,%r3,8
+ 	mtlr %r0
+ 	b .Lfinish
++#endif
+ 
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
+ 	lwz %r3,112+0(%r1)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
+ 	lwz %r3,112+0(%r1)
+ 	lwz %r4,112+4(%r1)
++#ifdef __LITTLE_ENDIAN__
++	mtlr %r0
++	b .Lfinish
++#else
+ 	li %r5,24
+ 	b .Lstruct567
++#endif
+ 
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
+ 	lwz %r3,112+0(%r1)
+ 	lwz %r4,112+4(%r1)
++#ifdef __LITTLE_ENDIAN__
++	mtlr %r0
++	b .Lfinish
++#else
+ 	li %r5,16
+ 	b .Lstruct567
++#endif
+ 
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
+ 	lwz %r3,112+0(%r1)
+ 	lwz %r4,112+4(%r1)
++#ifdef __LITTLE_ENDIAN__
++	mtlr %r0
++	b .Lfinish
++#else
+ 	li %r5,8
+ 	b .Lstruct567
++#endif
+ 
+ # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
+ 	lwz %r3,112+0(%r1)
+ 	lwz %r4,112+4(%r1)
+ 	mtlr %r0
+ 	b .Lfinish
+ 
++#ifndef __LITTLE_ENDIAN__
+ .Lstruct567:
+ 	subfic %r6,%r5,32
+ 	srw %r4,%r4,%r5
+ 	slw %r6,%r3,%r6
+ 	srw %r3,%r3,%r5
+ 	or %r4,%r6,%r4
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
++#endif
+ 
+ .Luint128:
+ 	lwz %r6,112+12(%r1)
+ 	mtlr %r0
+ 	addi %r1,%r1,144
+ 	blr
+ 
+ END(ffi_closure_SYSV)
+diff --git a/js/src/ctypes/libffi/src/powerpc/sysv.S b/js/src/ctypes/libffi/src/powerpc/sysv.S
+--- a/js/src/ctypes/libffi/src/powerpc/sysv.S
++++ b/js/src/ctypes/libffi/src/powerpc/sysv.S
+@@ -78,37 +78,41 @@ ENTRY(ffi_call_SYSV)
+ 	nop
+ 	lwz	%r7,-16-(4*4)(%r28)
+ 	lwz	%r8,-16-(3*4)(%r28)
+ 	lwz	%r9,-16-(2*4)(%r28)
+ 	lwz	%r10,-16-(1*4)(%r28)
+ 	nop
+ 1:
+ 
++#ifndef __NO_FPRS__
+ 	/* Load all the FP registers.  */
+ 	bf-	6,2f
+ 	lfd	%f1,-16-(8*4)-(8*8)(%r28)
+ 	lfd	%f2,-16-(8*4)-(7*8)(%r28)
+ 	lfd	%f3,-16-(8*4)-(6*8)(%r28)
+ 	lfd	%f4,-16-(8*4)-(5*8)(%r28)
+ 	nop
+ 	lfd	%f5,-16-(8*4)-(4*8)(%r28)
+ 	lfd	%f6,-16-(8*4)-(3*8)(%r28)
+ 	lfd	%f7,-16-(8*4)-(2*8)(%r28)
+ 	lfd	%f8,-16-(8*4)-(1*8)(%r28)
++#endif
+ 2:
+ 
+ 	/* Make the call.  */
+ 	bctrl
+ 
+ 	/* Now, deal with the return value.  */
+ 	mtcrf	0x01,%r31 /* cr7  */
+ 	bt-	31,L(small_struct_return_value)
+ 	bt-	30,L(done_return_value)
++#ifndef __NO_FPRS__
+ 	bt-	29,L(fp_return_value)
++#endif
+ 	stw	%r3,0(%r30)
+ 	bf+	28,L(done_return_value)
+ 	stw	%r4,4(%r30)
+ 	mtcrf	0x02,%r31 /* cr6  */
+ 	bf	27,L(done_return_value)
+ 	stw     %r5,8(%r30)
+ 	stw	%r6,12(%r30)
+ 	/* Fall through...  */
+@@ -119,41 +123,38 @@ L(done_return_value):
+ 	lwz	%r31, -4(%r28)
+ 	mtlr	%r9
+ 	lwz	%r30, -8(%r28)
+ 	lwz	%r29,-12(%r28)
+ 	lwz	%r28,-16(%r28)
+ 	lwz	%r1,0(%r1)
+ 	blr
+ 
++#ifndef __NO_FPRS__
+ L(fp_return_value):
+ 	bf	28,L(float_return_value)
+ 	stfd	%f1,0(%r30)
+ 	mtcrf   0x02,%r31 /* cr6  */
+ 	bf	27,L(done_return_value)
+ 	stfd	%f2,8(%r30)
+ 	b	L(done_return_value)
+ L(float_return_value):
+ 	stfs	%f1,0(%r30)
+ 	b	L(done_return_value)
++#endif
+ 
+ L(small_struct_return_value):
+-	extrwi	%r6,%r31,2,19         /* number of bytes padding = shift/8 */
+-	mtcrf	0x02,%r31	      /* copy flags to cr[24:27] (cr6) */
+-	extrwi	%r5,%r31,5,19         /* r5 <- number of bits of padding */
+-	subfic  %r6,%r6,4             /* r6 <- number of useful bytes in r3 */
+-	bf-	25,L(done_return_value) /* struct in r3 ? if not, done. */
+-/* smst_one_register: */
+-	slw	%r3,%r3,%r5           /* Left-justify value in r3 */
+-	mtxer	%r6                   /* move byte count to XER ... */
+-	stswx	%r3,0,%r30            /* ... and store that many bytes */
+-	bf+	26,L(done_return_value)  /* struct in r3:r4 ? */
+-	add	%r6,%r6,%r30          /* adjust pointer */
+-	stswi	%r4,%r6,4             /* store last four bytes */
+-	b	L(done_return_value)
++	/*
++	 * The C code always allocates a properly-aligned 8-byte bounce
++	 * buffer to make this assembly code very simple.  Just write out
++	 * r3 and r4 to the buffer to allow the C code to handle the rest.
++	 */
++	stw %r3, 0(%r30)
++	stw %r4, 4(%r30)
++	b L(done_return_value)
+ 
+ .LFE1:
+ END(ffi_call_SYSV)
+ 
+       .section	".eh_frame",EH_FRAME_FLAGS,@progbits
+ .Lframe1:
+       .4byte    .LECIE1-.LSCIE1  /*  Length of Common Information Entry */
+ .LSCIE1:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-ppc64le-mfbt.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,47 @@
+# HG changeset patch
+# Parent 147a75fe8f8e4a43b66f9716659e1209d7f5a950
+# User Ulrich Weigand <uweigand@de.ibm.com>
+Bug 976648 - powerpc64le-linux support - mfbt endian config
+
+diff --git a/mfbt/Endian.h b/mfbt/Endian.h
+--- a/mfbt/Endian.h
++++ b/mfbt/Endian.h
+@@ -86,17 +86,17 @@
+ #    error "CPU type is unknown"
+ #  endif
+ #elif defined(_WIN32)
+ #  if defined(_M_IX86)
+ #    define MOZ_LITTLE_ENDIAN 1
+ #  else
+ #    error "CPU type is unknown"
+ #  endif
+-#elif defined(__APPLE__)
++#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__)
+ #  if __LITTLE_ENDIAN__
+ #    define MOZ_LITTLE_ENDIAN 1
+ #  elif __BIG_ENDIAN__
+ #    define MOZ_BIG_ENDIAN 1
+ #  endif
+ #elif defined(__GNUC__) && \
+       defined(__BYTE_ORDER__) && \
+       defined(__ORDER_LITTLE_ENDIAN__) && \
+@@ -114,18 +114,17 @@
+ #  endif
+ /*
+  * We can't include useful headers like <endian.h> or <sys/isa_defs.h>
+  * here because they're not present on all platforms.  Instead we have
+  * this big conditional that ideally will catch all the interesting
+  * cases.
+  */
+ #elif defined(__sparc) || defined(__sparc__) || \
+-      defined(_POWER) || defined(__powerpc__) || \
+-      defined(__ppc__) || defined(__hppa) || \
++      defined(_POWER) || defined(__hppa) || \
+       defined(_MIPSEB) || defined(__ARMEB__) || \
+       defined(__s390__) || \
+       (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \
+       (defined(__ia64) && defined(__BIG_ENDIAN__))
+ #  define MOZ_BIG_ENDIAN 1
+ #elif defined(__i386) || defined(__i386__) || \
+       defined(__x86_64) || defined(__x86_64__) || \
+       defined(_MIPSEL) || defined(__ARMEL__) || \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-ppc64le-webrtc.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,42 @@
+# HG changeset patch
+# Parent acbe154db4c912f3ac853c0671cd3d5e52b1e716
+# User Ulrich Weigand <uweigand@de.ibm.com>
+Bug 976648 - powerpc64le-linux support - WebRTC endian config
+
+diff --git a/media/webrtc/trunk/webrtc/typedefs.h b/media/webrtc/trunk/webrtc/typedefs.h
+--- a/media/webrtc/trunk/webrtc/typedefs.h
++++ b/media/webrtc/trunk/webrtc/typedefs.h
+@@ -47,23 +47,33 @@
+ //#define WEBRTC_ARCH_ARM_FAMILY
+ //#define WEBRTC_ARCH_ARMEL
+ #define WEBRTC_ARCH_32_BITS
+ #define WEBRTC_ARCH_LITTLE_ENDIAN
+ #define WEBRTC_LITTLE_ENDIAN
+ #elif defined(__powerpc64__)
+ #define WEBRTC_ARCH_PPC64 1
+ #define WEBRTC_ARCH_64_BITS 1
++#ifdef __LITTLE_ENDIAN__
++#define WEBRTC_ARCH_LITTLE_ENDIAN
++#define WEBRTC_LITTLE_ENDIAN
++#else
+ #define WEBRTC_ARCH_BIG_ENDIAN
+ #define WEBRTC_BIG_ENDIAN
++#endif
+ #elif defined(__ppc__) || defined(__powerpc__)
+ #define WEBRTC_ARCH_PPC 1
+ #define WEBRTC_ARCH_32_BITS 1
++#ifdef __LITTLE_ENDIAN__
++#define WEBRTC_ARCH_LITTLE_ENDIAN
++#define WEBRTC_LITTLE_ENDIAN
++#else
+ #define WEBRTC_ARCH_BIG_ENDIAN
+ #define WEBRTC_BIG_ENDIAN
++#endif
+ #elif defined(__sparc64__)
+ #define WEBRTC_ARCH_SPARC 1
+ #define WEBRTC_ARCH_64_BITS 1
+ #define WEBRTC_ARCH_BIG_ENDIAN
+ #define WEBRTC_BIG_ENDIAN
+ #elif defined(__sparc__)
+ #define WEBRTC_ARCH_SPARC 1
+ #define WEBRTC_ARCH_32_BITS 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-ppc64le-xpcom.patch	Sun Mar 16 10:38:59 2014 +0100
@@ -0,0 +1,404 @@
+# HG changeset patch
+# Parent 571f8d1f1501d31bd7c0d0affdc7cdc8b21203a0
+# User Ulrich Weigand <uweigand@de.ibm.com>
+Bug 976648 - powerpc64le-linux support - xptcall port
+
+diff --git a/xpcom/reflect/xptcall/src/md/unix/moz.build b/xpcom/reflect/xptcall/src/md/unix/moz.build
+--- a/xpcom/reflect/xptcall/src/md/unix/moz.build
++++ b/xpcom/reflect/xptcall/src/md/unix/moz.build
+@@ -228,16 +228,23 @@ if CONFIG['OS_TEST'] == 'powerpc64':
+     if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD'):
+           SOURCES += [
+               'xptcinvoke_asm_ppc64_linux.s',
+               'xptcinvoke_ppc64_linux.cpp',
+               'xptcstubs_asm_ppc64_linux.s',
+               'xptcstubs_ppc64_linux.cpp',
+           ]
+ 
++if CONFIG['OS_TEST'] == 'powerpc64le':
++    if CONFIG['OS_ARCH'] == 'Linux':
++          CPP_SOURCES += [
++              'xptcinvoke_ppc64_linux.cpp',
++              'xptcstubs_ppc64_linux.cpp',
++          ]
++
+ if CONFIG['OS_TEST'] in ('macppc', 'bebox', 'ofppc', 'prep', 'amigappc'):
+     if CONFIG['OS_ARCH'] == 'NetBSD':
+         SOURCES += [
+             'xptcinvoke_asm_ppc_netbsd.s',
+             'xptcinvoke_ppc_netbsd.cpp',
+             'xptcstubs_asm_ppc_netbsd.s',
+             'xptcstubs_ppc_netbsd.cpp',
+         ]
+diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s
+--- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s
++++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s
+@@ -12,90 +12,121 @@
+ .set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4
+ .set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9
+ .set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14
+ .set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19
+ .set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24
+ .set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29
+ .set f30,30; .set f31,31
+ 
++# The ABI defines a fixed stack frame area of 4 doublewords (ELFv2)
++# or 6 doublewords (ELFv1); the last of these doublewords is used
++# as TOC pointer save area.  The fixed area is followed by a parameter
++# save area of 8 doublewords (used for vararg routines), followed
++# by space for parameters passed on the stack.
++#
++# We set STACK_TOC to the offset of the TOC pointer save area, and
++# STACK_PARAMS to the offset of the first on-stack parameter.
++
++#if _CALL_ELF == 2
++#define STACK_TOC      24
++#define STACK_PARAMS   96
++#else
++#define STACK_TOC      40
++#define STACK_PARAMS   112
++#endif
+ 
+ #
+ # NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
+ #                    uint32_t paramCount, nsXPTCVariant* params)
+ #
+ 
++#if _CALL_ELF == 2
++        .section ".text"
++        .type   NS_InvokeByIndex,@function
++        .globl  NS_InvokeByIndex
++        .align 2
++NS_InvokeByIndex:
++0:      addis 2,12,(.TOC.-0b)@ha
++        addi 2,2,(.TOC.-0b)@l
++        .localentry NS_InvokeByIndex,.-NS_InvokeByIndex
++#else
+         .section ".toc","aw"
+         .section ".text"
+         .align 2
+         .globl  NS_InvokeByIndex
+         .section ".opd","aw"
+         .align 3
+ NS_InvokeByIndex:
+         .quad   .NS_InvokeByIndex,.TOC.@tocbase
+         .previous
+         .type   NS_InvokeByIndex,@function
+ .NS_InvokeByIndex:
++#endif
+         mflr    0
+         std     0,16(r1)
+ 
+         std     r29,-24(r1)
+         std     r30,-16(r1)
+         std     r31,-8(r1)
+ 
+         mr      r29,r3                  # Save 'that' in r29
+         mr      r30,r4                  # Save 'methodIndex' in r30
+         mr      r31,r1                  # Save old frame
+ 
+         # Allocate stack frame with space for params. Since at least the
+         # first 7 parameters (not including 'that') will be in registers,
+         # we don't actually need stack space for those. We must ensure
+         # that the stack remains 16-byte aligned.
+         #
+-        #  | ..128-byte stack frame.. |     | 7 GP | 13 FP | 3 NV |
+-        #  |               |(params)........| regs | regs  | regs |
+-        # (r1)...........(+112)....(+128)
+-        #                               (-23*8).(-16*8).(-3*8)..(r31)
++        #  | (fixed area + |                | 7 GP | 13 FP | 3 NV |
++        #  |  param. save) |(params)........| regs | regs  | regs |
++        # (r1)......(+STACK_PARAMS)...  (-23*8).(-16*8).(-3*8)..(r31)
+ 
+         # +stack frame, -unused stack params, +regs storage, +1 for alignment
+-        addi    r7,r5,((112/8)-7+7+13+3+1)
++        addi    r7,r5,((STACK_PARAMS/8)-7+7+13+3+1)
+         rldicr  r7,r7,3,59              # multiply by 8 and mask with ~15
+         neg     r7,r7
+         stdux   r1,r1,r7
+ 
+ 
+         # Call invoke_copy_to_stack(uint64_t* gpregs, double* fpregs,
+         #                           uint32_t paramCount, nsXPTCVariant* s, 
+         #                           uint64_t* d))
+ 
+         # r5, r6 are passed through intact (paramCount, params)
+-        # r7 (d) has to be r1+112 -- where parameters are passed on the stack.
++        # r7 (d) has to be r1+STACK_PARAMS
++        #        -- where parameters are passed on the stack.
+         # r3, r4 are above that, easier to address from r31 than from r1
+ 
+         subi    r3,r31,(23*8)           # r3 --> GPRS
+         subi    r4,r31,(16*8)           # r4 --> FPRS
+-        addi    r7,r1,112               # r7 --> params
++        addi    r7,r1,STACK_PARAMS      # r7 --> params
+         bl      invoke_copy_to_stack
+         nop
+ 
+         # Set up to invoke function
+ 
+         ld      r9,0(r29)               # vtable (r29 is 'that')
+         mr      r3,r29                  # self is first arg, obviously
+ 
+         sldi    r30,r30,3               # Find function descriptor 
+         add     r9,r9,r30
+-        ld      r9,0(r9)
++        ld      r12,0(r9)
+ 
+-        ld      r0,0(r9)                # Actual address from fd.
+-        std     r2,40(r1)               # Save r2 (TOC pointer)
++        std     r2,STACK_TOC(r1)        # Save r2 (TOC pointer)
+ 
++#if _CALL_ELF == 2
++        mtctr   r12
++#else
++        ld      r0,0(r12)               # Actual address from fd.
+         mtctr   0
+-        ld      r11,16(r9)              # Environment pointer from fd.
+-        ld      r2,8(r9)                # TOC pointer from fd.
++        ld      r11,16(r12)             # Environment pointer from fd.
++        ld      r2,8(r12)               # TOC pointer from fd.
++#endif
+ 
+         # Load FP and GP registers as required
+         ld      r4, -(23*8)(r31) 
+         ld      r5, -(22*8)(r31) 
+         ld      r6, -(21*8)(r31) 
+         ld      r7, -(20*8)(r31) 
+         ld      r8, -(19*8)(r31) 
+         ld      r9, -(18*8)(r31) 
+@@ -112,21 +143,25 @@ NS_InvokeByIndex:
+         lfd     f9, -(8*8)(r31)
+         lfd     f10, -(7*8)(r31)
+         lfd     f11, -(6*8)(r31)
+         lfd     f12, -(5*8)(r31)
+         lfd     f13, -(4*8)(r31)
+ 
+         bctrl                           # Do it
+ 
+-        ld      r2,40(r1)               # Load our own TOC pointer
++        ld      r2,STACK_TOC(r1)        # Load our own TOC pointer
+         ld      r1,0(r1)                # Revert stack frame
+         ld      0,16(r1)                # Reload lr
+         ld      29,-24(r1)              # Restore NVGPRS
+         ld      30,-16(r1)
+         ld      31,-8(r1)
+         mtlr    0
+         blr
+ 
++#if _CALL_ELF == 2
++        .size   NS_InvokeByIndex,.-NS_InvokeByIndex
++#else
+         .size   NS_InvokeByIndex,.-.NS_InvokeByIndex
++#endif
+ 
+         # Magic indicating no need for an executable stack
+         .section .note.GNU-stack, "", @progbits ; .previous
+diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
+--- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
++++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
+@@ -69,17 +69,19 @@ invoke_copy_to_stack(uint64_t* gpregs,
+             else
+                 *(double *)d = s->val.d;
+         }
+         else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) {
+             if (i < FPR_COUNT) {
+                 fpregs[i]   = s->val.f; // if passed in registers, floats are promoted to doubles
+             } else {
+                 float *p = (float *)d;
++#ifndef __LITTLE_ENDIAN__
+                 p++;
++#endif
+                 *p = s->val.f;
+             }
+         }
+         else {
+             if (i < GPR_COUNT)
+                 gpregs[i] = tempu64;
+             else
+                 *d = tempu64;
+diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s
+--- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s
++++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s
+@@ -12,28 +12,50 @@
+ .set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4
+ .set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9
+ .set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14
+ .set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19
+ .set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24
+ .set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29
+ .set f30,30; .set f31,31
+ 
++#if _CALL_ELF == 2
++#define STACK_PARAMS   96
++#else
++#define STACK_PARAMS   112
++#endif
++
++#if _CALL_ELF == 2
++        .section ".text"
++        .type   SharedStub,@function
++        .globl  SharedStub
++        # Make the symbol hidden so that the branch from the stub does
++        # not go via a PLT.  This is not only better for performance,
++        # but may be necessary to avoid linker errors since there is
++        # no place to restore the TOC register in a sibling call.
++        .hidden SharedStub
++        .align 2
++SharedStub:
++0:      addis 2,12,(.TOC.-0b)@ha
++        addi 2,2,(.TOC.-0b)@l
++        .localentry SharedStub,.-SharedStub
++#else
+         .section ".text"
+         .align 2
+         .globl SharedStub
+         .section ".opd","aw"
+         .align 3
+ 
+ SharedStub:
+         .quad   .SharedStub,.TOC.@tocbase
+         .previous
+         .type   SharedStub,@function
+ 
+ .SharedStub:
++#endif
+         mflr    r0
+ 
+         std     r4, -56(r1)                     # Save all GPRS
+         std     r5, -48(r1)
+         std     r6, -40(r1)
+         std     r7, -32(r1)
+         std     r8, -24(r1)
+         std     r9, -16(r1)
+@@ -50,17 +72,17 @@ SharedStub:
+         stfd    f5, -128(r1)
+         stfd    f4, -136(r1)
+         stfd    f3, -144(r1)
+         stfd    f2, -152(r1)
+         stfd    f1, -160(r1)
+ 
+         subi    r6,r1,56                        # r6 --> gprData
+         subi    r7,r1,160                       # r7 --> fprData
+-        addi    r5,r1,112                       # r5 --> extra stack args
++        addi    r5,r1,STACK_PARAMS              # r5 --> extra stack args
+ 
+         std     r0, 16(r1)
+ 	
+         stdu    r1,-288(r1)
+                                                 # r3 has the 'self' pointer
+                                                 # already
+ 
+         mr      r4,r11                          # r4 is methodIndex selector,
+@@ -70,12 +92,16 @@ SharedStub:
+         bl      PrepareAndDispatch
+         nop
+ 
+         ld      1,0(r1)                         # restore stack
+         ld      r0,16(r1)                       # restore LR
+         mtlr    r0
+         blr
+ 
++#if _CALL_ELF == 2
++        .size   SharedStub,.-SharedStub
++#else
+         .size   SharedStub,.-.SharedStub
++#endif
+ 
+         # Magic indicating no need for an executable stack
+         .section .note.GNU-stack, "", @progbits ; .previous
+diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
+--- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
++++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
+@@ -78,17 +78,19 @@ PrepareAndDispatch(nsXPTCStubBase* self,
+                 dp->val.d = fprData[i];
+             else
+                 dp->val.d = *(double*) ap;
+         } else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
+             if (i < FPR_COUNT)
+                 dp->val.f = (float) fprData[i]; // in registers floats are passed as doubles
+             else {
+                 float *p = (float *)ap;
++#ifndef __LITTLE_ENDIAN__
+                 p++;
++#endif
+                 dp->val.f = *p;
+             }
+         } else { /* integer type or pointer */
+             if (i < GPR_COUNT)
+                 tempu64 = gprData[i];
+             else
+                 tempu64 = *ap;
+ 
+@@ -148,16 +150,53 @@ PrepareAndDispatch(nsXPTCStubBase* self,
+ // Create names would be like:
+ // _ZN14nsXPTCStubBase5Stub1Ev
+ // _ZN14nsXPTCStubBase6Stub12Ev
+ // _ZN14nsXPTCStubBase7Stub123Ev
+ // _ZN14nsXPTCStubBase8Stub1234Ev
+ // etc.
+ // Use assembler directives to get the names right...
+ 
++#if _CALL_ELF == 2
++# define STUB_ENTRY(n)                                                  \
++__asm__ (                                                               \
++        ".section \".text\" \n\t"                                       \
++        ".align 2 \n\t"                                                 \
++        ".if "#n" < 10 \n\t"                                            \
++        ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t"                    \
++        ".type  _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n"          \
++"_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t"                                  \
++        "0: addis 2,12,.TOC.-0b@ha \n\t"                                \
++        "addi     2,2,.TOC.-0b@l \n\t"                                  \
++        ".localentry _ZN14nsXPTCStubBase5Stub"#n"Ev,.-_ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \
++                                                                        \
++        ".elseif "#n" < 100 \n\t"                                       \
++        ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t"                    \
++        ".type  _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n"          \
++"_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t"                                  \
++        "0: addis 2,12,.TOC.-0b@ha \n\t"                                \
++        "addi     2,2,.TOC.-0b@l \n\t"                                  \
++        ".localentry _ZN14nsXPTCStubBase6Stub"#n"Ev,.-_ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \
++                                                                        \
++        ".elseif "#n" < 1000 \n\t"                                      \
++        ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t"                    \
++        ".type  _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n"          \
++"_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t"                                  \
++        "0: addis 2,12,.TOC.-0b@ha \n\t"                                \
++        "addi     2,2,.TOC.-0b@l \n\t"                                  \
++        ".localentry _ZN14nsXPTCStubBase7Stub"#n"Ev,.-_ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \
++                                                                        \
++        ".else  \n\t"                                                   \
++        ".err   \"stub number "#n" >= 1000 not yet supported\"\n"       \
++        ".endif \n\t"                                                   \
++                                                                        \
++        "li     11,"#n" \n\t"                                           \
++        "b      SharedStub \n"                                          \
++);
++#else
+ # define STUB_ENTRY(n)                                                  \
+ __asm__ (                                                               \
+         ".section \".toc\",\"aw\" \n\t"                                 \
+         ".section \".text\" \n\t"                                       \
+         ".align 2 \n\t"                                                 \
+         ".if "#n" < 10 \n\t"                                            \
+         ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t"                    \
+         ".section \".opd\",\"aw\" \n\t"                                 \
+@@ -190,16 +229,17 @@ PrepareAndDispatch(nsXPTCStubBase* self,
+                                                                         \
+         ".else  \n\t"                                                   \
+         ".err   \"stub number "#n" >= 1000 not yet supported\"\n"       \
+         ".endif \n\t"                                                   \
+                                                                         \
+         "li     11,"#n" \n\t"                                           \
+         "b      SharedStub \n"                                          \
+ );
++#endif
+ 
+ #define SENTINEL_ENTRY(n)                                               \
+ nsresult nsXPTCStubBase::Sentinel##n()                                  \
+ {                                                                       \
+     NS_ERROR("nsXPTCStubBase::Sentinel called");                  \
+     return NS_ERROR_NOT_IMPLEMENTED;                                    \
+ }
+ 
--- a/mozilla-ppc64le.patch	Sun Mar 16 09:27:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-# HG changeset patch
-# Parent e4ca21871e28639789930658e135a14f86069919
-# User Ulrich Weigand <uweigand@de.ibm.com>
-General PPC64 LE support
-
-diff --git a/configure.in b/configure.in
---- a/configure.in
-+++ b/configure.in
-@@ -1082,17 +1082,17 @@ esac
- 
- # Only set CPU_ARCH if we recognize the value of OS_TEST
- 
- case "$OS_TEST" in
- *86 | i86pc)
-     CPU_ARCH=x86
-     ;;
- 
--powerpc64 | ppc64)
-+powerpc64 | ppc64 | powerpc64le | ppc64le)
-     CPU_ARCH=ppc64
-     ;;
- 
- powerpc | ppc | rs6000)
-     CPU_ARCH=ppc
-     ;;
- 
- Alpha | alpha | ALPHA)
-diff --git a/js/src/assembler/wtf/Platform.h b/js/src/assembler/wtf/Platform.h
---- a/js/src/assembler/wtf/Platform.h
-+++ b/js/src/assembler/wtf/Platform.h
-@@ -160,26 +160,32 @@
- /* WTF_CPU_PPC - PowerPC 32-bit */
- #if   defined(__ppc__)     \
-     || defined(__PPC__)     \
-     || defined(__powerpc__) \
-     || defined(__powerpc)   \
-     || defined(__POWERPC__) \
-     || defined(_M_PPC)      \
-     || defined(__PPC)
-+#if !defined(__ppc64__) && !defined(__PPC64__)
- #define WTF_CPU_PPC 1
-+#endif
-+#if !defined(__LITTLE_ENDIAN__)
- #define WTF_CPU_BIG_ENDIAN 1
- #endif
-+#endif
- 
- /* WTF_CPU_PPC64 - PowerPC 64-bit */
- #if   defined(__ppc64__) \
-     || defined(__PPC64__)
- #define WTF_CPU_PPC64 1
-+#if !defined(__LITTLE_ENDIAN__)
- #define WTF_CPU_BIG_ENDIAN 1
- #endif
-+#endif
- 
- /* WTF_CPU_SH4 - SuperH SH-4 */
- #if defined(__SH4__)
- #define WTF_CPU_SH4 1
- #endif
- 
- /* WTF_CPU_SPARC32 - SPARC 32-bit */
- #if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8)
-diff --git a/js/src/configure.in b/js/src/configure.in
---- a/js/src/configure.in
-+++ b/js/src/configure.in
-@@ -923,17 +923,17 @@ esac
- 
- # Only set CPU_ARCH if we recognize the value of OS_TEST
- 
- case "$OS_TEST" in
- *86 | i86pc)
-     CPU_ARCH=x86
-     ;;
- 
--powerpc64 | ppc64)
-+powerpc64 | ppc64 | powerpc64le | ppc64le)
-     CPU_ARCH=ppc64
-     ;;
- 
- powerpc | ppc | rs6000)
-     CPU_ARCH=ppc
-     ;;
- 
- Alpha | alpha | ALPHA)
-diff --git a/js/src/jscpucfg.h b/js/src/jscpucfg.h
---- a/js/src/jscpucfg.h
-+++ b/js/src/jscpucfg.h
-@@ -22,17 +22,17 @@
- 
- # ifdef __WATCOMC__
- #  define HAVE_VA_LIST_AS_ARRAY 1
- # endif
- 
- # define IS_LITTLE_ENDIAN 1
- # undef  IS_BIG_ENDIAN
- 
--#elif defined(__APPLE__)
-+#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__)
- # if __LITTLE_ENDIAN__
- #  define IS_LITTLE_ENDIAN 1
- #  undef  IS_BIG_ENDIAN
- # elif __BIG_ENDIAN__
- #  undef  IS_LITTLE_ENDIAN
- #  define IS_BIG_ENDIAN 1
- # endif
- 
-@@ -84,18 +84,17 @@
- #  if defined(_STACK_GROWS_UPWARD)
- #   define JS_STACK_GROWTH_DIRECTION (1)
- #  elif defined(_STACK_GROWS_DOWNWARD)
- #   define JS_STACK_GROWTH_DIRECTION (-1)
- #  endif
- # endif
- 
- #elif defined(__sparc) || defined(__sparc__) || \
--      defined(_POWER) || defined(__powerpc__) || \
--      defined(__ppc__) || defined(__hppa) || \
-+      defined(_POWER) || defined(__hppa) || \
-       defined(_MIPSEB) || defined(_BIG_ENDIAN)
- /* IA64 running HP-UX will have _BIG_ENDIAN defined.
-  * IA64 running Linux will have endian.h and be handled above.
-  */
- # undef IS_LITTLE_ENDIAN
- # define IS_BIG_ENDIAN 1
- 
- #else /* !defined(__sparc) && !defined(__sparc__) && ... */
-diff --git a/media/webrtc/trunk/webrtc/typedefs.h b/media/webrtc/trunk/webrtc/typedefs.h
---- a/media/webrtc/trunk/webrtc/typedefs.h
-+++ b/media/webrtc/trunk/webrtc/typedefs.h
-@@ -47,23 +47,33 @@
- //#define WEBRTC_ARCH_ARM_FAMILY
- //#define WEBRTC_ARCH_ARMEL
- #define WEBRTC_ARCH_32_BITS
- #define WEBRTC_ARCH_LITTLE_ENDIAN
- #define WEBRTC_LITTLE_ENDIAN
- #elif defined(__powerpc64__)
- #define WEBRTC_ARCH_PPC64 1
- #define WEBRTC_ARCH_64_BITS 1
-+#ifdef __LITTLE_ENDIAN__
-+#define WEBRTC_ARCH_LITTLE_ENDIAN
-+#define WEBRTC_LITTLE_ENDIAN
-+#else
- #define WEBRTC_ARCH_BIG_ENDIAN
- #define WEBRTC_BIG_ENDIAN
-+#endif
- #elif defined(__ppc__) || defined(__powerpc__)
- #define WEBRTC_ARCH_PPC 1
- #define WEBRTC_ARCH_32_BITS 1
-+#ifdef __LITTLE_ENDIAN__
-+#define WEBRTC_ARCH_LITTLE_ENDIAN
-+#define WEBRTC_LITTLE_ENDIAN
-+#else
- #define WEBRTC_ARCH_BIG_ENDIAN
- #define WEBRTC_BIG_ENDIAN
-+#endif
- #elif defined(__sparc64__)
- #define WEBRTC_ARCH_SPARC 1
- #define WEBRTC_ARCH_64_BITS 1
- #define WEBRTC_ARCH_BIG_ENDIAN
- #define WEBRTC_BIG_ENDIAN
- #elif defined(__sparc__)
- #define WEBRTC_ARCH_SPARC 1
- #define WEBRTC_ARCH_32_BITS 1
-diff --git a/mfbt/Endian.h b/mfbt/Endian.h
---- a/mfbt/Endian.h
-+++ b/mfbt/Endian.h
-@@ -86,17 +86,17 @@
- #    error "CPU type is unknown"
- #  endif
- #elif defined(_WIN32)
- #  if defined(_M_IX86)
- #    define MOZ_LITTLE_ENDIAN 1
- #  else
- #    error "CPU type is unknown"
- #  endif
--#elif defined(__APPLE__)
-+#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__)
- #  if __LITTLE_ENDIAN__
- #    define MOZ_LITTLE_ENDIAN 1
- #  elif __BIG_ENDIAN__
- #    define MOZ_BIG_ENDIAN 1
- #  endif
- #elif defined(__GNUC__) && \
-       defined(__BYTE_ORDER__) && \
-       defined(__ORDER_LITTLE_ENDIAN__) && \
-@@ -114,18 +114,17 @@
- #  endif
- /*
-  * We can't include useful headers like <endian.h> or <sys/isa_defs.h>
-  * here because they're not present on all platforms.  Instead we have
-  * this big conditional that ideally will catch all the interesting
-  * cases.
-  */
- #elif defined(__sparc) || defined(__sparc__) || \
--      defined(_POWER) || defined(__powerpc__) || \
--      defined(__ppc__) || defined(__hppa) || \
-+      defined(_POWER) || defined(__hppa) || \
-       defined(_MIPSEB) || defined(__ARMEB__) || \
-       defined(__s390__) || \
-       (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \
-       (defined(__ia64) && defined(__BIG_ENDIAN__))
- #  define MOZ_BIG_ENDIAN 1
- #elif defined(__i386) || defined(__i386__) || \
-       defined(__x86_64) || defined(__x86_64__) || \
-       defined(_MIPSEL) || defined(__ARMEL__) || \
-diff --git a/nsprpub/pr/include/md/_linux.cfg b/nsprpub/pr/include/md/_linux.cfg
---- a/nsprpub/pr/include/md/_linux.cfg
-+++ b/nsprpub/pr/include/md/_linux.cfg
-@@ -24,18 +24,23 @@
- #elif defined(__GNU__)
- #define PR_AF_INET6 26  /* same as AF_INET6 */
- #else
- #define PR_AF_INET6 10  /* same as AF_INET6 */
- #endif
- 
- #ifdef __powerpc64__
- 
-+#ifdef __LITTLE_ENDIAN__
-+#define IS_LITTLE_ENDIAN 1
-+#undef  IS_BIG_ENDIAN
-+#else
- #undef  IS_LITTLE_ENDIAN
- #define IS_BIG_ENDIAN    1
-+#endif
- #define IS_64
- 
- #define PR_BYTES_PER_BYTE   1
- #define PR_BYTES_PER_SHORT  2
- #define PR_BYTES_PER_INT    4
- #define PR_BYTES_PER_INT64  8
- #define PR_BYTES_PER_LONG   8
- #define PR_BYTES_PER_FLOAT  4
-@@ -70,18 +75,23 @@
- #define PR_ALIGN_OF_POINTER 8
- #define PR_ALIGN_OF_WORD    8
- 
- #define PR_BYTES_PER_WORD_LOG2   3
- #define PR_BYTES_PER_DWORD_LOG2  3
- 
- #elif defined(__powerpc__)
- 
-+#ifdef __LITTLE_ENDIAN__
-+#define IS_LITTLE_ENDIAN 1
-+#undef  IS_BIG_ENDIAN
-+#else
- #undef  IS_LITTLE_ENDIAN
- #define IS_BIG_ENDIAN    1
-+#endif
- 
- #define PR_BYTES_PER_BYTE   1
- #define PR_BYTES_PER_SHORT  2
- #define PR_BYTES_PER_INT    4
- #define PR_BYTES_PER_INT64  8
- #define PR_BYTES_PER_LONG   4
- #define PR_BYTES_PER_FLOAT  4
- #define PR_BYTES_PER_DOUBLE 8
--- a/mozilla-xpcom-ppc64le.patch	Sun Mar 16 09:27:07 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-# HG changeset patch
-# Parent c5c0f80f1967fd1921e85b443ee87d097e4baf19
-# User Ulrich Weigand <uweigand@de.ibm.com>
-PPC64 LE support for XPCOM
-
-diff --git a/xpcom/reflect/xptcall/src/md/unix/moz.build b/xpcom/reflect/xptcall/src/md/unix/moz.build
---- a/xpcom/reflect/xptcall/src/md/unix/moz.build
-+++ b/xpcom/reflect/xptcall/src/md/unix/moz.build
-@@ -228,16 +228,23 @@ if CONFIG['OS_TEST'] == 'powerpc64':
-     if CONFIG['OS_ARCH'] in ('Linux', 'FreeBSD'):
-           SOURCES += [
-               'xptcinvoke_asm_ppc64_linux.s',
-               'xptcinvoke_ppc64_linux.cpp',
-               'xptcstubs_asm_ppc64_linux.s',
-               'xptcstubs_ppc64_linux.cpp',
-           ]
- 
-+if CONFIG['OS_TEST'] == 'powerpc64le':
-+    if CONFIG['OS_ARCH'] == 'Linux':
-+          CPP_SOURCES += [
-+              'xptcinvoke_ppc64_linux.cpp',
-+              'xptcstubs_ppc64_linux.cpp',
-+          ]
-+
- if CONFIG['OS_TEST'] in ('macppc', 'bebox', 'ofppc', 'prep', 'amigappc'):
-     if CONFIG['OS_ARCH'] == 'NetBSD':
-         SOURCES += [
-             'xptcinvoke_asm_ppc_netbsd.s',
-             'xptcinvoke_ppc_netbsd.cpp',
-             'xptcstubs_asm_ppc_netbsd.s',
-             'xptcstubs_ppc_netbsd.cpp',
-         ]
-diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s
---- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s
-+++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_ppc64_linux.s
-@@ -12,33 +12,51 @@
- .set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4
- .set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9
- .set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14
- .set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19
- .set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24
- .set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29
- .set f30,30; .set f31,31
- 
-+#if _CALL_ELF == 2
-+#define STACK_TOC      28
-+#define STACK_PARAMS   96
-+#else
-+#define STACK_TOC      40
-+#define STACK_PARAMS   112
-+#endif
- 
- #
- # NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex,
- #                    uint32_t paramCount, nsXPTCVariant* params)
- #
- 
-+#if _CALL_ELF == 2
-+        .section ".text"
-+        .type   NS_InvokeByIndex,@function
-+        .globl  NS_InvokeByIndex
-+        .align 2
-+NS_InvokeByIndex:
-+0:      addis 2,12,(.TOC.-0b)@ha
-+        addi 2,2,(.TOC.-0b)@l
-+        .localentry NS_InvokeByIndex,.-NS_InvokeByIndex
-+#else
-         .section ".toc","aw"
-         .section ".text"
-         .align 2
-         .globl  NS_InvokeByIndex
-         .section ".opd","aw"
-         .align 3
- NS_InvokeByIndex:
-         .quad   .NS_InvokeByIndex,.TOC.@tocbase
-         .previous
-         .type   NS_InvokeByIndex,@function
- .NS_InvokeByIndex:
-+#endif
-         mflr    0
-         std     0,16(r1)
- 
-         std     r29,-24(r1)
-         std     r30,-16(r1)
-         std     r31,-8(r1)
- 
-         mr      r29,r3                  # Save 'that' in r29
-@@ -51,51 +69,55 @@ NS_InvokeByIndex:
-         # that the stack remains 16-byte aligned.
-         #
-         #  | ..128-byte stack frame.. |     | 7 GP | 13 FP | 3 NV |
-         #  |               |(params)........| regs | regs  | regs |
-         # (r1)...........(+112)....(+128)
-         #                               (-23*8).(-16*8).(-3*8)..(r31)
- 
-         # +stack frame, -unused stack params, +regs storage, +1 for alignment
--        addi    r7,r5,((112/8)-7+7+13+3+1)
-+        addi    r7,r5,((STACK_PARAMS/8)-7+7+13+3+1)
-         rldicr  r7,r7,3,59              # multiply by 8 and mask with ~15
-         neg     r7,r7
-         stdux   r1,r1,r7
- 
- 
-         # Call invoke_copy_to_stack(uint64_t* gpregs, double* fpregs,
-         #                           uint32_t paramCount, nsXPTCVariant* s, 
-         #                           uint64_t* d))
- 
-         # r5, r6 are passed through intact (paramCount, params)
-         # r7 (d) has to be r1+112 -- where parameters are passed on the stack.
-         # r3, r4 are above that, easier to address from r31 than from r1
- 
-         subi    r3,r31,(23*8)           # r3 --> GPRS
-         subi    r4,r31,(16*8)           # r4 --> FPRS
--        addi    r7,r1,112               # r7 --> params
-+        addi    r7,r1,STACK_PARAMS      # r7 --> params
-         bl      invoke_copy_to_stack
-         nop
- 
-         # Set up to invoke function
- 
-         ld      r9,0(r29)               # vtable (r29 is 'that')
-         mr      r3,r29                  # self is first arg, obviously
- 
-         sldi    r30,r30,3               # Find function descriptor 
-         add     r9,r9,r30
--        ld      r9,0(r9)
-+        ld      r12,0(r9)
- 
--        ld      r0,0(r9)                # Actual address from fd.
--        std     r2,40(r1)               # Save r2 (TOC pointer)
-+        std     r2,STACK_TOC(r1)        # Save r2 (TOC pointer)
- 
-+#if _CALL_ELF == 2
-+        mtctr   r12
-+#else
-+        ld      r0,0(r12)               # Actual address from fd.
-         mtctr   0
--        ld      r11,16(r9)              # Environment pointer from fd.
--        ld      r2,8(r9)                # TOC pointer from fd.
-+        ld      r11,16(r12)             # Environment pointer from fd.
-+        ld      r2,8(r12)               # TOC pointer from fd.
-+#endif
- 
-         # Load FP and GP registers as required
-         ld      r4, -(23*8)(r31) 
-         ld      r5, -(22*8)(r31) 
-         ld      r6, -(21*8)(r31) 
-         ld      r7, -(20*8)(r31) 
-         ld      r8, -(19*8)(r31) 
-         ld      r9, -(18*8)(r31) 
-@@ -112,21 +134,25 @@ NS_InvokeByIndex:
-         lfd     f9, -(8*8)(r31)
-         lfd     f10, -(7*8)(r31)
-         lfd     f11, -(6*8)(r31)
-         lfd     f12, -(5*8)(r31)
-         lfd     f13, -(4*8)(r31)
- 
-         bctrl                           # Do it
- 
--        ld      r2,40(r1)               # Load our own TOC pointer
-+        ld      r2,STACK_TOC(r1)        # Load our own TOC pointer
-         ld      r1,0(r1)                # Revert stack frame
-         ld      0,16(r1)                # Reload lr
-         ld      29,-24(r1)              # Restore NVGPRS
-         ld      30,-16(r1)
-         ld      31,-8(r1)
-         mtlr    0
-         blr
- 
-+#if _CALL_ELF == 2
-+        .size   NS_InvokeByIndex,.-NS_InvokeByIndex
-+#else
-         .size   NS_InvokeByIndex,.-.NS_InvokeByIndex
-+#endif
- 
-         # Magic indicating no need for an executable stack
-         .section .note.GNU-stack, "", @progbits ; .previous
-diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
---- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
-+++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_ppc64_linux.cpp
-@@ -69,17 +69,19 @@ invoke_copy_to_stack(uint64_t* gpregs,
-             else
-                 *(double *)d = s->val.d;
-         }
-         else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) {
-             if (i < FPR_COUNT) {
-                 fpregs[i]   = s->val.f; // if passed in registers, floats are promoted to doubles
-             } else {
-                 float *p = (float *)d;
-+#ifndef __LITTLE_ENDIAN__
-                 p++;
-+#endif
-                 *p = s->val.f;
-             }
-         }
-         else {
-             if (i < GPR_COUNT)
-                 gpregs[i] = tempu64;
-             else
-                 *d = tempu64;
-diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s
---- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s
-+++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_ppc64_linux.s
-@@ -12,28 +12,50 @@
- .set f0,0; .set f1,1; .set f2,2; .set f3,3; .set f4,4
- .set f5,5; .set f6,6; .set f7,7; .set f8,8; .set f9,9
- .set f10,10; .set f11,11; .set f12,12; .set f13,13; .set f14,14
- .set f15,15; .set f16,16; .set f17,17; .set f18,18; .set f19,19
- .set f20,20; .set f21,21; .set f22,22; .set f23,23; .set f24,24
- .set f25,25; .set f26,26; .set f27,27; .set f28,28; .set f29,29
- .set f30,30; .set f31,31
- 
-+#if _CALL_ELF == 2
-+#define STACK_PARAMS   96
-+#else
-+#define STACK_PARAMS   112
-+#endif
-+
-+#if _CALL_ELF == 2
-+        .section ".text"
-+        .type   SharedStub,@function
-+        .globl  SharedStub
-+        # Make the symbol hidden so that the branch from the stub does
-+        # not go via a PLT.  This is not only better for performance,
-+        # but may be necessary to avoid linker errors since there is
-+        # no place to restore the TOC register in a sibling call.
-+        .hidden SharedStub
-+        .align 2
-+SharedStub:
-+0:      addis 2,12,(.TOC.-0b)@ha
-+        addi 2,2,(.TOC.-0b)@l
-+        .localentry SharedStub,.-SharedStub
-+#else
-         .section ".text"
-         .align 2
-         .globl SharedStub
-         .section ".opd","aw"
-         .align 3
- 
- SharedStub:
-         .quad   .SharedStub,.TOC.@tocbase
-         .previous
-         .type   SharedStub,@function
- 
- .SharedStub:
-+#endif
-         mflr    r0
- 
-         std     r4, -56(r1)                     # Save all GPRS
-         std     r5, -48(r1)
-         std     r6, -40(r1)
-         std     r7, -32(r1)
-         std     r8, -24(r1)
-         std     r9, -16(r1)
-@@ -50,17 +72,17 @@ SharedStub:
-         stfd    f5, -128(r1)
-         stfd    f4, -136(r1)
-         stfd    f3, -144(r1)
-         stfd    f2, -152(r1)
-         stfd    f1, -160(r1)
- 
-         subi    r6,r1,56                        # r6 --> gprData
-         subi    r7,r1,160                       # r7 --> fprData
--        addi    r5,r1,112                       # r5 --> extra stack args
-+        addi    r5,r1,STACK_PARAMS              # r5 --> extra stack args
- 
-         std     r0, 16(r1)
- 	
-         stdu    r1,-288(r1)
-                                                 # r3 has the 'self' pointer
-                                                 # already
- 
-         mr      r4,r11                          # r4 is methodIndex selector,
-@@ -70,12 +92,16 @@ SharedStub:
-         bl      PrepareAndDispatch
-         nop
- 
-         ld      1,0(r1)                         # restore stack
-         ld      r0,16(r1)                       # restore LR
-         mtlr    r0
-         blr
- 
-+#if _CALL_ELF == 2
-+        .size   SharedStub,.-SharedStub
-+#else
-         .size   SharedStub,.-.SharedStub
-+#endif
- 
-         # Magic indicating no need for an executable stack
-         .section .note.GNU-stack, "", @progbits ; .previous
-diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
---- a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
-+++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc64_linux.cpp
-@@ -78,17 +78,19 @@ PrepareAndDispatch(nsXPTCStubBase* self,
-                 dp->val.d = fprData[i];
-             else
-                 dp->val.d = *(double*) ap;
-         } else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
-             if (i < FPR_COUNT)
-                 dp->val.f = (float) fprData[i]; // in registers floats are passed as doubles
-             else {
-                 float *p = (float *)ap;
-+#ifndef __LITTLE_ENDIAN__
-                 p++;
-+#endif
-                 dp->val.f = *p;
-             }
-         } else { /* integer type or pointer */
-             if (i < GPR_COUNT)
-                 tempu64 = gprData[i];
-             else
-                 tempu64 = *ap;
- 
-@@ -148,16 +150,53 @@ PrepareAndDispatch(nsXPTCStubBase* self,
- // Create names would be like:
- // _ZN14nsXPTCStubBase5Stub1Ev
- // _ZN14nsXPTCStubBase6Stub12Ev
- // _ZN14nsXPTCStubBase7Stub123Ev
- // _ZN14nsXPTCStubBase8Stub1234Ev
- // etc.
- // Use assembler directives to get the names right...
- 
-+#if _CALL_ELF == 2
-+# define STUB_ENTRY(n)                                                  \
-+__asm__ (                                                               \
-+        ".section \".text\" \n\t"                                       \
-+        ".align 2 \n\t"                                                 \
-+        ".if "#n" < 10 \n\t"                                            \
-+        ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t"                    \
-+        ".type  _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n"          \
-+"_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t"                                  \
-+        "0: addis 2,12,.TOC.-0b@ha \n\t"                                \
-+        "addi     2,2,.TOC.-0b@l \n\t"                                  \
-+        ".localentry _ZN14nsXPTCStubBase5Stub"#n"Ev,.-_ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \
-+                                                                        \
-+        ".elseif "#n" < 100 \n\t"                                       \
-+        ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t"                    \
-+        ".type  _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n"          \
-+"_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t"                                  \
-+        "0: addis 2,12,.TOC.-0b@ha \n\t"                                \
-+        "addi     2,2,.TOC.-0b@l \n\t"                                  \
-+        ".localentry _ZN14nsXPTCStubBase6Stub"#n"Ev,.-_ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \
-+                                                                        \
-+        ".elseif "#n" < 1000 \n\t"                                      \
-+        ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t"                    \
-+        ".type  _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n"          \
-+"_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t"                                  \
-+        "0: addis 2,12,.TOC.-0b@ha \n\t"                                \
-+        "addi     2,2,.TOC.-0b@l \n\t"                                  \
-+        ".localentry _ZN14nsXPTCStubBase7Stub"#n"Ev,.-_ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \
-+                                                                        \
-+        ".else  \n\t"                                                   \
-+        ".err   \"stub number "#n" >= 1000 not yet supported\"\n"       \
-+        ".endif \n\t"                                                   \
-+                                                                        \
-+        "li     11,"#n" \n\t"                                           \
-+        "b      SharedStub \n"                                          \
-+);
-+#else
- # define STUB_ENTRY(n)                                                  \
- __asm__ (                                                               \
-         ".section \".toc\",\"aw\" \n\t"                                 \
-         ".section \".text\" \n\t"                                       \
-         ".align 2 \n\t"                                                 \
-         ".if "#n" < 10 \n\t"                                            \
-         ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t"                    \
-         ".section \".opd\",\"aw\" \n\t"                                 \
-@@ -190,16 +229,17 @@ PrepareAndDispatch(nsXPTCStubBase* self,
-                                                                         \
-         ".else  \n\t"                                                   \
-         ".err   \"stub number "#n" >= 1000 not yet supported\"\n"       \
-         ".endif \n\t"                                                   \
-                                                                         \
-         "li     11,"#n" \n\t"                                           \
-         "b      SharedStub \n"                                          \
- );
-+#endif
- 
- #define SENTINEL_ENTRY(n)                                               \
- nsresult nsXPTCStubBase::Sentinel##n()                                  \
- {                                                                       \
-     NS_ERROR("nsXPTCStubBase::Sentinel called");                  \
-     return NS_ERROR_NOT_IMPLEMENTED;                                    \
- }
- 
--- a/series	Sun Mar 16 09:27:07 2014 +0100
+++ b/series	Sun Mar 16 10:38:59 2014 +0100
@@ -17,9 +17,12 @@
 mozilla-ppc.patch
 mozilla-idldir.patch
 mozilla-libproxy-compat.patch
-mozilla-ppc64le.patch
-mozilla-libffi-ppc64le.patch
-mozilla-xpcom-ppc64le.patch
+mozilla-ppc64le-build.patch
+mozilla-ppc64le-javascript.patch
+mozilla-ppc64le-libffi.patch
+mozilla-ppc64le-mfbt.patch
+mozilla-ppc64le-webrtc.patch
+mozilla-ppc64le-xpcom.patch
 
 # Firefox patches
 firefox-browser-css.patch