diff -ruN gmp-5.0.3/ChangeLog gmp-5.0.4/ChangeLog
--- gmp-5.0.3/ChangeLog	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/ChangeLog	2012-02-10 11:23:05.000000000 +0100
@@ -1,7 +1,113 @@
+2012-02-10  Torbjorn Granlund  <tege@gmplib.org>
+
+	* Version 5.0.4 released.
+
+2012-02-09 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+	* gmp-impl.h (mpn_toom3*_itch): Support any recursion depth.
+	* tests/refmpn.c (refmpn_mul): Restore tight allocations.
+
+2012-02-09  Marc Glisse  <marc.glisse@inria.fr>
+
+	* gmp-impl.h (ABS_CAST): New macro.
+	* mpf/cmp_si.c: Use ABS_CAST.
+	* mpf/get_si.c: Use ABS_CAST.
+	* mpf/iset_si.c: Use ABS_CAST.
+	* mpf/set_si.c: Use ABS_CAST.
+	* mpq/set_si.c: Use ABS_CAST.
+	* mpz/cmp_si.c: Use ABS_CAST.
+	* mpz/get_si.c: Use ABS_CAST.
+	* mpz/iset_si.c: Use ABS_CAST.
+	* mpz/mul_i.h: Use ABS_CAST.
+	* mpz/set_si.c: Use ABS_CAST.
+
+2012-02-09  Torbjorn Granlund  <tege@gmplib.org>
+
+	* gmp-h.in (__GNU_MP_VERSION_PATCHLEVEL): Bump.
+
+	* Makefile.am (LIBGMP_LT_*, LIBGMPXX_LT_*, LIBMP_LT_*):
+	Bump version info.
+
+2012-02-08  Torbjorn Granlund  <tege@gmplib.org>
+
+	* mpn/powerpc32/divrem_2.asm: Fix off-by-one condition in invert_limb
+	code.
+
+2012-02-08  Niels Möller  <nisse@lysator.liu.se>
+
+	* doc/gmp.texi (mpz_gcdext): Describe cofactor canonicalization.
+	(mpn_gcdext): Copied doc updates from main repo.
+
+2012-02-07  Niels Möller  <nisse@lysator.liu.se>
+
+	* mpn/generic/gcdext.c (mpn_gcdext): Fixed assert, related to the
+	special case A = (2k+1) G, B = 2 G.
+
+2012-02-06  Niels Möller  <nisse@lysator.liu.se>
+
+	* mpn/generic/hgcd.c (hgcd_matrix_update_q): Fixed carry handling
+	bug.
+
+	* tests/mpz/t-gcd.c (main): Omit tests with urandomb operands.
+	* tests/mpn/t-hgcd.c (main): Likewise.
+
+2012-02-05  Niels Möller  <nisse@lysator.liu.se>
+
+	* tests/mpz/t-gcd.c (main): Add tests with rrandomb operands.
+	* tests/mpn/t-hgcd.c (main): Likewise.
+
+	* mpn/generic/gcdext_subdiv_step.c (mpn_gcdext_subdiv_step):
+	Bugfix, in u1 += q * u0, handle carry in all cases. Also normalize
+	the product q * u0.
+
+2012-02-04 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+	* tests/refmpn.c (refmpn_mul): More conservative allocations.
+
+2012-02-03  Torbjorn Granlund  <tege@gmplib.org>
+
+	* mpn/x86_64/bd1/gmp-mparam.h: New file.
+
+	* longlong.h (udiv_qrnnd from sdiv_qrnnd): Declare udiv_w_sdiv.
+
+	* mpn/generic/udiv_w_sdiv.c: Use c89 function header.
+
+2012-02-02 Marco Bodrato <bodrato@mail.dm.unipi.it>
+
+	* mpn/generic/toom_interpolate_16pts.c: Correct an unlikely 32-bit bug.
+
+2012-02-02  Torbjorn Granlund  <tege@gmplib.org>
+
+	* mpn/generic/toom63_mul.c: Allow s+t==n by adjusting an ASSERT.
+	* mpn/generic/toom_interpolate_8pts.c: Perform final incr iff s+t!=n.
+
+	* tests/mpn/t-toom6h.c (MIN_BN): Make more consistent with ASSERT in
+	tested function.
+
+2012-02-01  Torbjorn Granlund  <tege@gmplib.org>
+
+	* tests/mpn/t-mul.c: New file.
+	* tests/mpn/Makefile.am: Compile it.
+
+2012-01-31  Torbjorn Granlund  <tege@gmplib.org>
+
+	* mpn/generic/powm_sec.c (SQR_BASECASE_LIM): New name for
+	SQR_BASECASE_MAX.
+	(SQR_BASECASE_LIM, fat variant): Define to read __gmpn_cpuvec.
+	(SQR_BASECASE_LIM, native variant): Define to SQR_TOOM2_THRESHOLD
+	straight, without arithmetic.
+	(mpn_local_sqr): Use BELOW_THRESHOLD as per Marco's suggestion.
+
+2012-01-30  Torbjorn Granlund  <tege@gmplib.org>
+
+	* tests/mpz/t-powm.c: Ensure all sizes are seen.
+
 2012-01-27  Torbjorn Granlund  <tege@gmplib.org>
 
 	* Version 5.0.3 released.
 
+	* Upgrade to libtool 2.4.2.
+
 2012-01-25  Torbjorn Granlund  <tege@gmplib.org>
 
 	* tune/tuneup.c: Remove unused tuneup variables.
@@ -157,7 +263,7 @@
 
 	* configure.in: Support s390x.
 
-	* longlong.h: Add spport for 64-bit s390x.
+	* longlong.h: Add support for 64-bit s390x.
 
 	* mpn/s390_64: New directory.
 	* mpn/s390_32: Directory renamed from mpn/s390.
@@ -404,6 +510,11 @@
 	touch it. Fixed the case that no assembler files are used, and
 	GMP_PROG_M4 is omitted.
 
+2010-06-15  Niels Möller  <nisse@lysator.liu.se>
+
+	* tests/mpn/Makefile.am (check_PROGRAMS): Added t-mod_1.
+	* tests/mpn/t-mod_1.c: New file.
+
 2010-05-24  Torbjorn Granlund  <tege@gmplib.org>
 
 	* mpn/generic/mu_div_qr.c (mpn_preinv_mu_div_qr_itch): New function.
@@ -449,6 +560,11 @@
 	MOD_1_2_TO_MOD_1_4_THRESHOLD before MOD_1U_TO_MOD_1_1_THRESHOLD for
 	correctness.
 
+2010-04-12  Torbjorn Granlund  <tege@gmplib.org>
+
+	* tests/mpn/t-toom6h.c (SIZE_LOG): Define.
+	* tests/mpn/t-toom8h.c (SIZE_LOG): Likewise.
+
 2010-04-10  Torbjorn Granlund  <tege@gmplib.org>
 
 	* mpn/x86/divrem_2.asm: Use "orb" instead of "or" to work around
diff -ruN gmp-5.0.3/configure gmp-5.0.4/configure
--- gmp-5.0.3/configure	2012-01-27 09:59:34.000000000 +0100
+++ gmp-5.0.4/configure	2012-02-10 11:23:14.000000000 +0100
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.in Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for GNU MP 5.0.3.
+# Generated by GNU Autoconf 2.65 for GNU MP 5.0.4.
 #
 # Report bugs to <gmp-bugs@gmplib.org, see http://gmplib.org/manual/Reporting-Bugs.html>.
 #
@@ -585,8 +585,8 @@
 # Identity of this package.
 PACKAGE_NAME='GNU MP'
 PACKAGE_TARNAME='gmp'
-PACKAGE_VERSION='5.0.3'
-PACKAGE_STRING='GNU MP 5.0.3'
+PACKAGE_VERSION='5.0.4'
+PACKAGE_STRING='GNU MP 5.0.4'
 PACKAGE_BUGREPORT='gmp-bugs@gmplib.org, see http://gmplib.org/manual/Reporting-Bugs.html'
 PACKAGE_URL='http://www.gnu.org/software/gmp/'
 
@@ -1372,7 +1372,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures GNU MP 5.0.3 to adapt to many kinds of systems.
+\`configure' configures GNU MP 5.0.4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1442,7 +1442,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of GNU MP 5.0.3:";;
+     short | recursive ) echo "Configuration of GNU MP 5.0.4:";;
    esac
   cat <<\_ACEOF
 
@@ -1574,7 +1574,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-GNU MP configure 5.0.3
+GNU MP configure 5.0.4
 generated by GNU Autoconf 2.65
 
 Copyright (C) 2009 Free Software Foundation, Inc.
@@ -2608,7 +2608,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by GNU MP $as_me 5.0.3, which was
+It was created by GNU MP $as_me 5.0.4, which was
 generated by GNU Autoconf 2.65.  Invocation command line was
 
   $ $0 $@
@@ -3527,7 +3527,7 @@
 
 # Define the identity of the package.
  PACKAGE='gmp'
- VERSION='5.0.3'
+ VERSION='5.0.4'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -29899,7 +29899,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by GNU MP $as_me 5.0.3, which was
+This file was extended by GNU MP $as_me 5.0.4, which was
 generated by GNU Autoconf 2.65.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -29971,7 +29971,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-GNU MP config.status 5.0.3
+GNU MP config.status 5.0.4
 configured by $0, generated by GNU Autoconf 2.65,
   with options \\"\$ac_cs_config\\"
 
diff -ruN gmp-5.0.3/gmp-h.in gmp-5.0.4/gmp-h.in
--- gmp-5.0.3/gmp-h.in	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/gmp-h.in	2012-02-10 11:23:05.000000000 +0100
@@ -2273,7 +2273,7 @@
 /* Major version number is the value of __GNU_MP__ too, above and in mp.h. */
 #define __GNU_MP_VERSION 5
 #define __GNU_MP_VERSION_MINOR 0
-#define __GNU_MP_VERSION_PATCHLEVEL 3
+#define __GNU_MP_VERSION_PATCHLEVEL 4
 #define __GNU_MP_RELEASE (__GNU_MP_VERSION * 10000 + __GNU_MP_VERSION_MINOR * 100 + __GNU_MP_VERSION_PATCHLEVEL)
 
 #define __GMP_H__
diff -ruN gmp-5.0.3/gmp-impl.h gmp-5.0.4/gmp-impl.h
--- gmp-5.0.3/gmp-impl.h	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/gmp-impl.h	2012-02-10 11:23:05.000000000 +0100
@@ -4,7 +4,8 @@
    BE SUBJECT TO INCOMPATIBLE CHANGES IN FUTURE GNU MP RELEASES.
 
 Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003,
-2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
+Inc.
 
 This file is part of the GNU MP Library.
 
@@ -478,6 +479,7 @@
 #define UNLIKELY(cond)                 __GMP_UNLIKELY(cond)
 
 #define ABS(x) ((x) >= 0 ? (x) : -(x))
+#define ABS_CAST(T,x) ((x) >= 0 ? (T)(x) : -((T)((x) + 1) - 1))
 #undef MIN
 #define MIN(l,o) ((l) < (o) ? (l) : (o))
 #undef MAX
@@ -4519,12 +4521,17 @@
 #define mpn_toom2_sqr_itch(an) \
   (2 * ((an) + GMP_NUMB_BITS))
 
-/* Can probably be trimmed to 2 an + O(log an). */
+/* toom33/toom3: Scratch need is 5an/2 + 10k, k is the recursion depth.
+   We use 3an + C, so that we can use a smaller constant.
+ */
 #define mpn_toom33_mul_itch(an, bn) \
-  ((5 * (an) >> 1) + GMP_NUMB_BITS)
+  (3 * (an) + GMP_NUMB_BITS)
 #define mpn_toom3_sqr_itch(an) \
-  ((5 * (an) >> 1) + GMP_NUMB_BITS)
+  (3 * (an) + GMP_NUMB_BITS)
 
+/* toom33/toom3: Scratch need is 8an/3 + 13k, k is the recursion depth.
+   We use 3an + C, so that we can use a smaller constant.
+ */
 #define mpn_toom44_mul_itch(an, bn) \
   (3 * (an) + GMP_NUMB_BITS)
 #define mpn_toom4_sqr_itch(an) \
diff -ruN gmp-5.0.3/longlong.h gmp-5.0.4/longlong.h
--- gmp-5.0.3/longlong.h	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/longlong.h	2012-02-10 11:23:05.000000000 +0100
@@ -2014,6 +2014,7 @@
     (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d);				\
     (r) = __r;								\
   } while (0)
+__GMP_DECLSPEC UWtype __MPN(udiv_w_sdiv) (UWtype *, UWtype, UWtype, UWtype);
 #endif
 
 /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
diff -ruN gmp-5.0.3/Makefile.am gmp-5.0.4/Makefile.am
--- gmp-5.0.3/Makefile.am	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/Makefile.am	2012-02-10 11:23:05.000000000 +0100
@@ -69,6 +69,7 @@
 #        5.0.1   10:1:0    6:1:2   4:21:1
 #        5.0.2   10:2:0    6:2:2   4:22:1
 #        5.0.3   10:3:0    6:3:2   4:23:1
+#        5.0.4   10:4:0    6:4:2   4:24:1
 #
 # Starting at 3:0:0 is a slight abuse of the versioning system, but it
 # ensures we're past soname libgmp.so.2, which was used on Debian GNU/Linux
@@ -82,15 +83,15 @@
 # libgmpxx.so.3.0.4) incrementing, to make it clear which GMP it's from.
 
 LIBGMP_LT_CURRENT =  10
-LIBGMP_LT_REVISION = 3
+LIBGMP_LT_REVISION = 4
 LIBGMP_LT_AGE =      0
 
 LIBGMPXX_LT_CURRENT =  6
-LIBGMPXX_LT_REVISION = 3
+LIBGMPXX_LT_REVISION = 4
 LIBGMPXX_LT_AGE =      2
 
 LIBMP_LT_CURRENT =  4
-LIBMP_LT_REVISION = 23
+LIBMP_LT_REVISION = 24
 LIBMP_LT_AGE =      1
 
 
diff -ruN gmp-5.0.3/Makefile.in gmp-5.0.4/Makefile.in
--- gmp-5.0.3/Makefile.in	2012-01-27 09:59:37.000000000 +0100
+++ gmp-5.0.4/Makefile.in	2012-02-10 11:23:18.000000000 +0100
@@ -414,6 +414,7 @@
 #        5.0.1   10:1:0    6:1:2   4:21:1
 #        5.0.2   10:2:0    6:2:2   4:22:1
 #        5.0.3   10:3:0    6:3:2   4:23:1
+#        5.0.4   10:4:0    6:4:2   4:24:1
 #
 # Starting at 3:0:0 is a slight abuse of the versioning system, but it
 # ensures we're past soname libgmp.so.2, which was used on Debian GNU/Linux
@@ -426,13 +427,13 @@
 # it's still good to get the shared library filename (like
 # libgmpxx.so.3.0.4) incrementing, to make it clear which GMP it's from.
 LIBGMP_LT_CURRENT = 10
-LIBGMP_LT_REVISION = 3
+LIBGMP_LT_REVISION = 4
 LIBGMP_LT_AGE = 0
 LIBGMPXX_LT_CURRENT = 6
-LIBGMPXX_LT_REVISION = 3
+LIBGMPXX_LT_REVISION = 4
 LIBGMPXX_LT_AGE = 2
 LIBMP_LT_CURRENT = 4
-LIBMP_LT_REVISION = 23
+LIBMP_LT_REVISION = 24
 LIBMP_LT_AGE = 1
 SUBDIRS = tests mpn mpz mpq mpf printf scanf cxx mpbsd demos tune doc
 
diff -ruN gmp-5.0.3/mpf/cmp_si.c gmp-5.0.4/mpf/cmp_si.c
--- gmp-5.0.3/mpf/cmp_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpf/cmp_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -29,6 +29,7 @@
   mp_exp_t uexp;
   mp_limb_t ulimb;
   int usign;
+  unsigned long abs_vval;
 
   uexp = u->_mp_exp;
   usize = u->_mp_size;
@@ -55,13 +56,13 @@
 
   usign = usize >= 0 ? 1 : -1;
   usize = ABS (usize);
-  vval = ABS (vval);
+  abs_vval = ABS_CAST (unsigned long, vval);
 
   /* 2. Are the exponents different (V's exponent == 1)?  */
 #if GMP_NAIL_BITS != 0
-  if (uexp > 1 + ((unsigned long) vval > GMP_NUMB_MAX))
+  if (uexp > 1 + (abs_vval > GMP_NUMB_MAX))
     return usign;
-  if (uexp < 1 + ((unsigned long) vval > GMP_NUMB_MAX))
+  if (uexp < 1 + (abs_vval > GMP_NUMB_MAX))
     return -usign;
 #else
   if (uexp > 1)
@@ -85,9 +86,9 @@
   usize--;
 
   /* 3. Compare the most significant mantissa limb with V.  */
-  if (ulimb > (unsigned long) vval)
+  if (ulimb > abs_vval)
     return usign;
-  else if (ulimb < (unsigned long) vval)
+  else if (ulimb < abs_vval)
     return -usign;
 
   /* Ignore zeroes at the low end of U.  */
diff -ruN gmp-5.0.3/mpf/get_si.c gmp-5.0.4/mpf/get_si.c
--- gmp-5.0.3/mpf/get_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpf/get_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -72,5 +72,5 @@
     return fl & LONG_MAX;
   else
     /* this form necessary to correctly handle -0x80..00 */
-    return ~ ((fl - 1) & LONG_MAX);
+    return -1 - (long) ((fl - 1) & LONG_MAX);
 }
diff -ruN gmp-5.0.3/mpf/iset_si.c gmp-5.0.4/mpf/iset_si.c
--- gmp-5.0.3/mpf/iset_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpf/iset_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -31,7 +31,7 @@
   r->_mp_prec = prec;
   r->_mp_d = (mp_ptr) (*__gmp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
 
-  vl = (mp_limb_t) (unsigned long int) (val >= 0 ? val : -val);
+  vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
 
   r->_mp_d[0] = vl & GMP_NUMB_MASK;
   size = vl != 0;
diff -ruN gmp-5.0.3/mpf/set_si.c gmp-5.0.4/mpf/set_si.c
--- gmp-5.0.3/mpf/set_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpf/set_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -27,7 +27,7 @@
   mp_size_t size;
   mp_limb_t vl;
 
-  vl = (mp_limb_t) (unsigned long int) (val >= 0 ? val : -val);
+  vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
 
   dest->_mp_d[0] = vl & GMP_NUMB_MASK;
   size = vl != 0;
diff -ruN gmp-5.0.3/mpn/generic/gcdext.c gmp-5.0.4/mpn/generic/gcdext.c
--- gmp-5.0.3/mpn/generic/gcdext.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/gcdext.c	2012-02-10 11:23:05.000000000 +0100
@@ -386,7 +386,10 @@
       MPN_COPY (gp, ap, n);
 
       MPN_CMP (c, u0, u1, un);
-      ASSERT (c != 0);
+      /* c == 0 can happen only when A = (2k+1) G, B = 2 G. And in
+	 this case we choose the cofactor + 1, corresponding to G = A
+	 - k B, rather than -1, corresponding to G = - A + (k+1) B. */
+      ASSERT (c != 0 || (un == 1 && u0[0] == 1 && u1[0] == 1));
       if (c < 0)
 	{
 	  MPN_NORMALIZE (u0, un);
diff -ruN gmp-5.0.3/mpn/generic/gcdext_subdiv_step.c gmp-5.0.4/mpn/generic/gcdext_subdiv_step.c
--- gmp-5.0.3/mpn/generic/gcdext_subdiv_step.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/gcdext_subdiv_step.c	2012-02-10 11:23:05.000000000 +0100
@@ -181,15 +181,17 @@
 
       if (qn + u0n > un)
 	{
-	  ASSERT_NOCARRY (mpn_add (u1, tp, qn + u0n, u1, un));
+	  mp_size_t u1n = un;
 	  un = qn + u0n;
-	  un -= (u1[un-1] == 0);
+	  un -= (tp[un-1] == 0);
+	  u1[un] = mpn_add (u1, tp, un, u1, u1n);
 	}
       else
 	{
 	  u1[un] = mpn_add (u1, u1, un, tp, qn + u0n);
-	  un += (u1[un] > 0);
 	}
+
+      un += (u1[un] > 0);
     }
 
   *unp = un;
diff -ruN gmp-5.0.3/mpn/generic/hgcd.c gmp-5.0.4/mpn/generic/hgcd.c
--- gmp-5.0.3/mpn/generic/hgcd.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/hgcd.c	2012-02-10 11:23:05.000000000 +0100
@@ -115,8 +115,8 @@
       if (c[0] | c[1])
 	{
 	  M->n = n + qn + 1;
-	  M->p[0][col][n-1] = c[0];
-	  M->p[1][col][n-1] = c[1];
+	  M->p[0][col][M->n - 1] = c[0];
+	  M->p[1][col][M->n - 1] = c[1];
 	}
       else
 	{
diff -ruN gmp-5.0.3/mpn/generic/powm_sec.c gmp-5.0.4/mpn/generic/powm_sec.c
--- gmp-5.0.3/mpn/generic/powm_sec.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/powm_sec.c	2012-02-10 11:23:05.000000000 +0100
@@ -82,7 +82,7 @@
 
 #if ! HAVE_NATIVE_mpn_sqr_basecase
 /* The limit of the generic code is SQR_TOOM2_THRESHOLD.  */
-#define SQR_BASECASE_MAX  SQR_TOOM2_THRESHOLD
+#define SQR_BASECASE_LIM  SQR_TOOM2_THRESHOLD
 #endif
 
 #if HAVE_NATIVE_mpn_sqr_basecase
@@ -91,20 +91,19 @@
    mpn_sqr_basecase, it comes from SQR_TOOM2_THRESHOLD_MAX in the assembly
    file.  An assembly mpn_sqr_basecase that does not define it, should allow
    any size.  */
-#define SQR_BASECASE_MAX  SQR_TOOM2_THRESHOLD
+#define SQR_BASECASE_LIM  SQR_TOOM2_THRESHOLD
 #endif
 #endif
 
 #ifdef WANT_FAT_BINARY
-/* For fat builds, we would need to quantify over all mpn_sqr_basecase limit
-   that may appear in __gmpn_cpuvec.  This asks for some configure.in hacking.
-   For now, define a safe limit which all mpn_sqr_basecase will handle.
-   FIXME!  */
-#define SQR_BASECASE_MAX 32
+/* For fat builds, we use SQR_TOOM2_THRESHOLD which will expand to a read from
+   __gmpn_cpuvec.  Perhaps any possible sqr_basecase.asm allow any size, and we
+   limit the use unnecessarily.  We cannot tell, so play it safe.  FIXME.  */
+#define SQR_BASECASE_LIM  SQR_TOOM2_THRESHOLD
 #endif
 
-#ifndef SQR_BASECASE_MAX
-/* If SQR_BASECASE_MAX is now not defined, use mpn_sqr_basecase for any operand
+#ifndef SQR_BASECASE_LIM
+/* If SQR_BASECASE_LIM is now not defined, use mpn_sqr_basecase for any operand
    size.  */
 #define mpn_local_sqr(rp,up,n,tp) mpn_sqr_basecase(rp,up,n)
 #else
@@ -118,7 +117,7 @@
   ASSERT (n >= 1);
   ASSERT (! MPN_OVERLAP_P (rp, 2*n, up, n));
 
-  if (n <= SQR_BASECASE_MAX)
+  if (BELOW_THRESHOLD (n, SQR_BASECASE_LIM))
     {
       mpn_sqr_basecase (rp, up, n);
       return;
diff -ruN gmp-5.0.3/mpn/generic/toom63_mul.c gmp-5.0.4/mpn/generic/toom63_mul.c
--- gmp-5.0.3/mpn/generic/toom63_mul.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/toom63_mul.c	2012-02-10 11:23:05.000000000 +0100
@@ -6,7 +6,7 @@
    SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES.  IN FACT, IT IS ALMOST
    GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
 
-Copyright 2009 Free Software Foundation, Inc.
+Copyright 2009, 2012 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -105,8 +105,8 @@
 
   ASSERT (0 < s && s <= n);
   ASSERT (0 < t && t <= n);
-  /* WARNING! it assumes s+t>n */
-  ASSERT ( s + t > n );
+  /* WARNING! it assumes s+t>=n */
+  ASSERT ( s + t >= n );
   ASSERT ( s + t > 4);
   /* WARNING! it assumes n>1 */
   ASSERT ( n > 2);
diff -ruN gmp-5.0.3/mpn/generic/toom_interpolate_16pts.c gmp-5.0.4/mpn/generic/toom_interpolate_16pts.c
--- gmp-5.0.3/mpn/generic/toom_interpolate_16pts.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/toom_interpolate_16pts.c	2012-02-10 11:23:05.000000000 +0100
@@ -6,7 +6,7 @@
    SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES.  IN FACT, IT IS ALMOST
    GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE.
 
-Copyright 2009, 2010 Free Software Foundation, Inc.
+Copyright 2009, 2010, 2012 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -299,11 +299,15 @@
     DO_mpn_subrsh(r5, n3p1, r0, spt, 4, wsi);
 
     cy = DO_mpn_sublsh_n (r1 + BIT_CORRECTION, r0, spt, 42 - CORRECTION_BITS, wsi);
-    MPN_DECR_U (r1 + spt + BIT_CORRECTION, n3p1 - spt - BIT_CORRECTION, cy);
 #if BIT_CORRECTION
+    cy = mpn_sub_1 (r1 + spt + BIT_CORRECTION, r1 + spt + BIT_CORRECTION,
+		    n3p1 - spt - BIT_CORRECTION, cy);
+    ASSERT (BIT_CORRECTION > 0 || cy == 0);
     /* FIXME: assumes r7[n3p1] is writable (it is if r5 follows). */
     cy = r7[n3p1];
     r7[n3p1] = 0x80;
+#else
+    MPN_DECR_U (r1 + spt + BIT_CORRECTION, n3p1 - spt - BIT_CORRECTION, cy);
 #endif
     DO_mpn_subrsh(r7, n3p1 + BIT_CORRECTION, r0, spt, 6, wsi);
 #if BIT_CORRECTION
diff -ruN gmp-5.0.3/mpn/generic/toom_interpolate_8pts.c gmp-5.0.4/mpn/generic/toom_interpolate_8pts.c
--- gmp-5.0.3/mpn/generic/toom_interpolate_8pts.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/toom_interpolate_8pts.c	2012-02-10 11:23:05.000000000 +0100
@@ -188,5 +188,8 @@
   cy = mpn_add_1 (pp + 6*n, r3 + n, n, pp[6*n]);
   MPN_INCR_U (r3 + 2*n, n + 1, cy);
   cy = r3[3*n] + mpn_add_n (pp + 7*n, pp + 7*n, r3 + 2*n, n);
-  MPN_INCR_U (pp + 8*n, spt - n, cy);
+  if (LIKELY(spt != n))
+    MPN_INCR_U (pp + 8*n, spt - n, cy);
+  else
+    ASSERT (cy == 0);
 }
diff -ruN gmp-5.0.3/mpn/generic/udiv_w_sdiv.c gmp-5.0.4/mpn/generic/udiv_w_sdiv.c
--- gmp-5.0.3/mpn/generic/udiv_w_sdiv.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/generic/udiv_w_sdiv.c	2012-02-10 11:23:05.000000000 +0100
@@ -9,7 +9,7 @@
    GNU MP RELEASE.
 
 
-Copyright 1992, 1994, 1996, 2000 Free Software Foundation, Inc.
+Copyright 1992, 1994, 1996, 2000, 2011, 2012 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -31,8 +31,7 @@
 #include "longlong.h"
 
 mp_limb_t
-mpn_udiv_w_sdiv (rp, a1, a0, d)
-     mp_limb_t *rp, a1, a0, d;
+mpn_udiv_w_sdiv (mp_limb_t *rp, mp_limb_t a1, mp_limb_t a0, mp_limb_t d)
 {
   mp_limb_t q, r;
   mp_limb_t c0, c1, b1;
diff -ruN gmp-5.0.3/mpn/pa32/gmp-mparam.h gmp-5.0.4/mpn/pa32/gmp-mparam.h
--- gmp-5.0.3/mpn/pa32/gmp-mparam.h	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/pa32/gmp-mparam.h	2012-02-10 11:23:05.000000000 +0100
@@ -1,7 +1,7 @@
 /* HP-PA 1.0 gmp-mparam.h -- Compiler/machine parameter header file.
 
-Copyright 1991, 1993, 1994, 1999, 2000, 2001, 2002 Free Software Foundation,
-Inc.
+Copyright 1991, 1993, 1994, 1999, 2000, 2001, 2002, 2012 Free Software
+Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
@@ -24,14 +24,14 @@
 /* These values are for the PA7100 using GCC.  */
 /* Generated by tuneup.c, 2000-10-27. */
 
-#ifndef MUL_TOOM22_THRESHOLD   
+#ifndef MUL_TOOM22_THRESHOLD
 #define MUL_TOOM22_THRESHOLD      30
 #endif
 #ifndef MUL_TOOM33_THRESHOLD
 #define MUL_TOOM33_THRESHOLD     141
 #endif
 
-#ifndef SQR_TOOM2_THRESHOLD    
+#ifndef SQR_TOOM2_THRESHOLD
 #define SQR_TOOM2_THRESHOLD       59
 #endif
 #ifndef SQR_TOOM3_THRESHOLD
@@ -39,15 +39,13 @@
 #endif
 
 #ifndef DIV_DC_THRESHOLD
-#define DIV_DC_THRESHOLD             108
+#define DIV_DC_THRESHOLD         108
 #endif
 
 #ifndef POWM_THRESHOLD
 #define POWM_THRESHOLD            18
 #endif
 
-#ifndef GCD_ACCEL_THRESHOLD
-#define GCD_ACCEL_THRESHOLD       46
-#endif
+#ifndef GCDEXT_THRESHOLD
 #define GCDEXT_THRESHOLD          33
 #endif
diff -ruN gmp-5.0.3/mpn/powerpc32/divrem_2.asm gmp-5.0.4/mpn/powerpc32/divrem_2.asm
--- gmp-5.0.3/mpn/powerpc32/divrem_2.asm	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpn/powerpc32/divrem_2.asm	2012-02-10 11:23:05.000000000 +0100
@@ -1,6 +1,6 @@
 dnl  PPC-32 mpn_divrem_2 -- Divide an mpn number by a normalized 2-limb number.
 
-dnl  Copyright 2007, 2008 Free Software Foundation, Inc.
+dnl  Copyright 2007, 2008, 2012 Free Software Foundation, Inc.
 
 dnl  This file is part of the GNU MP Library.
 
@@ -84,9 +84,9 @@
 	bge-	cr7, L(9)
 	add	r0, r0, r10
 	cmplw	cr7, r0, r10
-	cmplw	cr6, r0, r6
+	cmplw	cr6, r6, r0
 	addi	r31, r31, -1		C q1--
-	cror	28, 28, 25
+	crorc	28, 28, 25
 	bc+	12, 28, L(9)
 	addi	r31, r31, -1		C q1--
 	add	r0, r0, r10
@@ -101,9 +101,9 @@
 	bge-	cr7, L(13)
 	add	r0, r0, r10
 	cmplw	cr7, r0, r10
-	cmplw	cr6, r0, r11
+	cmplw	cr6, r11, r0
 	addi	r6, r6, -1		C q0--
-	cror	28, 28, 25
+	crorc	28, 28, 25
 	bc+	12, 28, L(13)
 C	add	r0, r0, r10		C final remainder
 	addi	r6, r6, -1		C q0--
diff -ruN gmp-5.0.3/mpn/x86_64/bd1/gmp-mparam.h gmp-5.0.4/mpn/x86_64/bd1/gmp-mparam.h
--- gmp-5.0.3/mpn/x86_64/bd1/gmp-mparam.h	1970-01-01 01:00:00.000000000 +0100
+++ gmp-5.0.4/mpn/x86_64/bd1/gmp-mparam.h	2012-02-10 11:23:05.000000000 +0100
@@ -0,0 +1,182 @@
+/* AMD Bulldozer-1 gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright 1991, 1993, 1994, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+2008, 2009, 2010, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MP Library 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+#define GMP_LIMB_BITS 64
+#define BYTES_PER_MP_LIMB 8
+
+#define MOD_1_NORM_THRESHOLD                 0  /* always */
+#define MOD_1_UNNORM_THRESHOLD               0  /* always */
+#define MOD_1N_TO_MOD_1_1_THRESHOLD          7
+#define MOD_1U_TO_MOD_1_1_THRESHOLD          5
+#define MOD_1_1_TO_MOD_1_2_THRESHOLD         0  /* never mpn_mod_1_1p */
+#define MOD_1_2_TO_MOD_1_4_THRESHOLD        12
+#define PREINV_MOD_1_TO_MOD_1_THRESHOLD     14
+#define USE_PREINV_DIVREM_1                  1  /* native */
+#define DIVEXACT_1_THRESHOLD                 0  /* always (native) */
+#define BMOD_1_TO_MOD_1_THRESHOLD           24
+
+#define MUL_TOOM22_THRESHOLD                18
+#define MUL_TOOM33_THRESHOLD                53
+#define MUL_TOOM44_THRESHOLD               154
+#define MUL_TOOM6H_THRESHOLD               274
+#define MUL_TOOM8H_THRESHOLD               466
+
+#define MUL_TOOM32_TO_TOOM43_THRESHOLD      97
+#define MUL_TOOM32_TO_TOOM53_THRESHOLD     140
+#define MUL_TOOM42_TO_TOOM53_THRESHOLD     105
+#define MUL_TOOM42_TO_TOOM63_THRESHOLD     109
+
+#define SQR_BASECASE_THRESHOLD               0  /* always (native) */
+#define SQR_TOOM2_THRESHOLD                 24
+#define SQR_TOOM3_THRESHOLD                 85
+#define SQR_TOOM4_THRESHOLD                119
+#define SQR_TOOM6_THRESHOLD                318
+#define SQR_TOOM8_THRESHOLD                502
+
+#define MULMOD_BNM1_THRESHOLD               11
+#define SQRMOD_BNM1_THRESHOLD               16
+
+#define MUL_FFT_MODF_THRESHOLD             412  /* k = 5 */
+#define MUL_FFT_TABLE3                                      \
+  { {    412, 5}, {     19, 6}, {     10, 5}, {     21, 6}, \
+    {     11, 5}, {     23, 6}, {     21, 7}, {     11, 6}, \
+    {     23, 7}, {     21, 8}, {     11, 7}, {     25, 8}, \
+    {     13, 7}, {     28, 8}, {     15, 7}, {     31, 8}, \
+    {     21, 9}, {     11, 8}, {     27, 9}, {     15, 8}, \
+    {     33, 9}, {     19, 8}, {     41, 9}, {     23, 8}, \
+    {     47, 9}, {     27,10}, {     15, 9}, {     31, 8}, \
+    {     63, 9}, {     39,10}, {     23, 9}, {     51,11}, \
+    {     15,10}, {     31, 9}, {     67,10}, {     39, 9}, \
+    {     79,10}, {     47, 9}, {     95,10}, {     55,11}, \
+    {     31,10}, {     79,11}, {     47,10}, {    103,12}, \
+    {     31,11}, {     63,10}, {    127,11}, {     79,10}, \
+    {    175,11}, {     95,10}, {    191,12}, {     63,11}, \
+    {    127,10}, {    255,11}, {    143,10}, {    287,11}, \
+    {    159,12}, {     95,13}, {     63,12}, {    127,11}, \
+    {    271, 9}, {   1087,11}, {    287,10}, {    575,11}, \
+    {    303,12}, {    159,11}, {    319,10}, {    671,11}, \
+    {    351,12}, {    191,11}, {    383,10}, {    767,11}, \
+    {    415,12}, {    223,11}, {    447,13}, {    127,12}, \
+    {    255,11}, {    543,12}, {    287,11}, {    575,10}, \
+    {   1215,12}, {    319,11}, {    639,12}, {    351,13}, \
+    {    191,12}, {    383,11}, {    767,12}, {    415,11}, \
+    {    831,10}, {   1663,12}, {    447,14}, {    127,13}, \
+    {    255,12}, {    543,11}, {   1087,10}, {   2175,12}, \
+    {    575,11}, {   1151,12}, {    607,11}, {   1215,13}, \
+    {    319,12}, {    639,11}, {   1279,12}, {    671,11}, \
+    {   1343,10}, {   2687,12}, {    703,13}, {    383,12}, \
+    {    767,11}, {   1535,12}, {    831,13}, {    447,12}, \
+    {    959,14}, {    255,13}, {    511,12}, {   1087,11}, \
+    {   2175,13}, {    575,12}, {   1215,11}, {   2431,10}, \
+    {   4863,13}, {    639,12}, {   1343,11}, {   2687,13}, \
+    {    703,12}, {   1407,14}, {    383,13}, {    767,12}, \
+    {   1535,13}, {    831,12}, {   1663,13}, {    959,15}, \
+    {    255,14}, {    511,13}, {   1087,12}, {   2175,13}, \
+    {   1215,12}, {   2431,11}, {   4863,14}, {    639,13}, \
+    {   1343,12}, {   2687,13}, {   1471,12}, {   2943,11}, \
+    {   5887,14}, {    767,13}, {   1599,12}, {   3199,13}, \
+    {   1727,14}, {    895,13}, {   1919,12}, {   3839,15}, \
+    {    511,14}, {   1023,13}, {   2175,14}, {   1151,13}, \
+    {   2431,12}, {   4863,14}, {  16384,15}, {  32768,16}, \
+    {  65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+    {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define MUL_FFT_TABLE3_SIZE 168
+#define MUL_FFT_THRESHOLD                 4736
+
+#define SQR_FFT_MODF_THRESHOLD             368  /* k = 5 */
+#define SQR_FFT_TABLE3                                      \
+  { {    368, 5}, {     19, 6}, {     10, 5}, {     21, 6}, \
+    {     21, 7}, {     11, 6}, {     23, 7}, {     21, 8}, \
+    {     11, 7}, {     25, 8}, {     13, 7}, {     28, 8}, \
+    {     15, 7}, {     31, 8}, {     17, 7}, {     35, 8}, \
+    {     19, 7}, {     39, 8}, {     27, 9}, {     15, 8}, \
+    {     35, 9}, {     19, 8}, {     41, 9}, {     23, 8}, \
+    {     47, 9}, {     27,10}, {     15, 9}, {     39,10}, \
+    {     23, 9}, {     51,11}, {     15,10}, {     31, 9}, \
+    {     67,10}, {     39, 9}, {     79,10}, {     47, 9}, \
+    {     95,10}, {     55,11}, {     31,10}, {     79,11}, \
+    {     47,10}, {     95,12}, {     31,11}, {     63,10}, \
+    {    135,11}, {     79,10}, {    159,11}, {     95,10}, \
+    {    191,11}, {    111,12}, {     63,11}, {    127,10}, \
+    {    255, 9}, {    543,11}, {    143, 9}, {    575,12}, \
+    {     95,11}, {    191,13}, {     63,12}, {    127,11}, \
+    {    255,10}, {    511,11}, {    271,10}, {    543,11}, \
+    {    287,10}, {    575,11}, {    303,12}, {    159,11}, \
+    {    335,12}, {    191,11}, {    415,12}, {    223,11}, \
+    {    447,10}, {    895,13}, {    127,12}, {    255,11}, \
+    {    319,11}, {    639,10}, {   1279,12}, {    351,13}, \
+    {    191,12}, {    383,11}, {    767,12}, {    415,11}, \
+    {    831,10}, {   1663,12}, {    447,11}, {    895,14}, \
+    {    127,13}, {    255,12}, {    511,11}, {   1023,12}, \
+    {    543,11}, {   1087,10}, {   2175,12}, {    575,11}, \
+    {   1151,12}, {    607,13}, {    319,12}, {    639,11}, \
+    {   1279,12}, {    671,11}, {   1343,10}, {   2687,12}, \
+    {    703,13}, {    383,12}, {    767,11}, {   1599,12}, \
+    {    831,13}, {    447,12}, {    959,14}, {    255,13}, \
+    {    511,12}, {   1087,11}, {   2175,13}, {    575,12}, \
+    {   1151,11}, {   2303,12}, {   1215,11}, {   2431,10}, \
+    {   4863,13}, {    639,12}, {   1343,11}, {   2687,13}, \
+    {    703,12}, {   1407,14}, {    383,13}, {    767,12}, \
+    {   1599,13}, {    831,12}, {   1727,13}, {    895,15}, \
+    {    255,14}, {    511,13}, {   1087,12}, {   2175,13}, \
+    {   1215,12}, {   2431,11}, {   4863,14}, {    639,13}, \
+    {   1343,12}, {   2687,13}, {   1471,12}, {   2943,11}, \
+    {   5887,14}, {    767,13}, {   1599,12}, {   3199,13}, \
+    {   1727,14}, {    895,13}, {   1919,12}, {   3839,15}, \
+    {    511,14}, {   1023,13}, {   2175,14}, {   1151,13}, \
+    {   2431,12}, {   4863,14}, {  16384,15}, {  32768,16}, \
+    {  65536,17}, { 131072,18}, { 262144,19}, { 524288,20}, \
+    {1048576,21}, {2097152,22}, {4194304,23}, {8388608,24} }
+#define SQR_FFT_TABLE3_SIZE 172
+#define SQR_FFT_THRESHOLD                 3264
+
+#define MULLO_BASECASE_THRESHOLD             4
+#define MULLO_DC_THRESHOLD                  30
+#define MULLO_MUL_N_THRESHOLD             8648
+
+#define DC_DIV_QR_THRESHOLD                 38
+#define DC_DIVAPPR_Q_THRESHOLD             187
+#define DC_BDIV_QR_THRESHOLD                48
+#define DC_BDIV_Q_THRESHOLD                 92
+
+#define INV_MULMOD_BNM1_THRESHOLD           49
+#define INV_NEWTON_THRESHOLD               202
+#define INV_APPR_THRESHOLD                 197
+
+#define BINV_NEWTON_THRESHOLD              246
+#define REDC_1_TO_REDC_2_THRESHOLD          55
+#define REDC_2_TO_REDC_N_THRESHOLD           0  /* anomaly: never REDC_2 */
+
+#define MU_DIV_QR_THRESHOLD               1470
+#define MU_DIVAPPR_Q_THRESHOLD            1470
+#define MUPI_DIV_QR_THRESHOLD               90
+#define MU_BDIV_QR_THRESHOLD              1187
+#define MU_BDIV_Q_THRESHOLD               1470
+
+#define MATRIX22_STRASSEN_THRESHOLD         15
+#define HGCD_THRESHOLD                      96
+#define GCD_DC_THRESHOLD                   400
+#define GCDEXT_DC_THRESHOLD                288
+#define JACOBI_BASE_METHOD                   1
+
+#define GET_STR_DC_THRESHOLD                12
+#define GET_STR_PRECOMPUTE_THRESHOLD        27
+#define SET_STR_DC_THRESHOLD               172
+#define SET_STR_PRECOMPUTE_THRESHOLD      1341
diff -ruN gmp-5.0.3/mpq/set_si.c gmp-5.0.4/mpq/set_si.c
--- gmp-5.0.3/mpq/set_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpq/set_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -35,7 +35,7 @@
       return;
     }
 
-  abs_num = ABS (num);
+  abs_num = ABS_CAST (unsigned long, num);
 
   if (num == 0)
     {
diff -ruN gmp-5.0.3/mpz/cmp_si.c gmp-5.0.4/mpz/cmp_si.c
--- gmp-5.0.3/mpz/cmp_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpz/cmp_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -28,6 +28,7 @@
   mp_size_t usize = u->_mp_size;
   mp_size_t vsize;
   mp_limb_t u_digit;
+  unsigned long int absv_digit = (unsigned long int) v_digit;
 
 #if GMP_NAIL_BITS != 0
   /* FIXME.  This isn't very pretty.  */
@@ -45,7 +46,7 @@
   else if (v_digit < 0)
     {
       vsize = -1;
-      v_digit = -v_digit;
+      absv_digit = -absv_digit;
     }
 
   if (usize != vsize)
@@ -56,10 +57,10 @@
 
   u_digit = u->_mp_d[0];
 
-  if (u_digit == (mp_limb_t) (unsigned long) v_digit)
+  if (u_digit == (mp_limb_t) absv_digit)
     return 0;
 
-  if (u_digit > (mp_limb_t) (unsigned long) v_digit)
+  if (u_digit > (mp_limb_t) absv_digit)
     return usize;
   else
     return -usize;
diff -ruN gmp-5.0.3/mpz/get_si.c gmp-5.0.4/mpz/get_si.c
--- gmp-5.0.3/mpz/get_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpz/get_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -34,10 +34,10 @@
 #endif
 
   if (size > 0)
-    return (long) zl & LONG_MAX;
+    return zl & LONG_MAX;
   else if (size < 0)
     /* This expression is necessary to properly handle 0x80000000 */
-    return ~(((long) zl - 1L) & LONG_MAX);
+    return -1 - (long) ((zl - 1) & LONG_MAX);
   else
     return 0;
 }
diff -ruN gmp-5.0.3/mpz/iset_si.c gmp-5.0.4/mpz/iset_si.c
--- gmp-5.0.3/mpz/iset_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpz/iset_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -31,7 +31,7 @@
   dest->_mp_alloc = 1;
   dest->_mp_d = (mp_ptr) (*__gmp_allocate_func) (BYTES_PER_MP_LIMB);
 
-  vl = (mp_limb_t) (unsigned long int) (val >= 0 ? val : -val);
+  vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
 
   dest->_mp_d[0] = vl & GMP_NUMB_MASK;
   size = vl != 0;
diff -ruN gmp-5.0.3/mpz/mul_i.h gmp-5.0.4/mpz/mul_i.h
--- gmp-5.0.3/mpz/mul_i.h	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpz/mul_i.h	2012-02-10 11:23:05.000000000 +0100
@@ -26,7 +26,7 @@
 #ifdef OPERATION_mul_si
 #define FUNCTION               mpz_mul_si
 #define MULTIPLICAND_UNSIGNED
-#define MULTIPLICAND_ABS(x)    ((unsigned long) ABS(x))
+#define MULTIPLICAND_ABS(x)    ABS_CAST(unsigned long, (x))
 #endif
 
 #ifdef OPERATION_mul_ui
diff -ruN gmp-5.0.3/mpz/set_si.c gmp-5.0.4/mpz/set_si.c
--- gmp-5.0.3/mpz/set_si.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/mpz/set_si.c	2012-02-10 11:23:05.000000000 +0100
@@ -27,7 +27,7 @@
   mp_size_t size;
   mp_limb_t vl;
 
-  vl = (mp_limb_t) (unsigned long int) (val >= 0 ? val : -val);
+  vl = (mp_limb_t) ABS_CAST (unsigned long int, val);
 
   dest->_mp_d[0] = vl & GMP_NUMB_MASK;
   size = vl != 0;
diff -ruN gmp-5.0.3/NEWS gmp-5.0.4/NEWS
--- gmp-5.0.3/NEWS	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/NEWS	2012-02-10 11:23:05.000000000 +0100
@@ -5,6 +5,44 @@
 medium, provided this notice is preserved.
 
 
+Changes between GMP version 5.0.3 and 5.0.4
+
+  BUGS FIXED
+  * Thresholds in mpn_powm_sec for both fat and non-fat builds are now used
+    safely, plugging a one-word buffer overrun introduced in the 5.0.3 release
+    (for non-fat) and a multi-word buffer overrun that existed since 5.0 (for
+    fat).  (We have not been able to provoke malign stack smashing in any of
+    the ~100 configurations explored by the GMP nightly builds, but the bug
+    should be assumed to be exploitable.)
+
+  * Two bugs in multiplication code causing incorrect computation with
+    extremely low probability have been fixed.
+
+  * A bug in the test suite causing buffer overruns during "make check",
+    sometimes leading to subsequent malloc crashes, has been fixed.
+
+  * Two bugs in the gcd code have been fixed.  They could lead to incorrect
+    results, but for uniformly distributed random operands, the likelihood for
+    that is infinitesimally small.  (There was also a third bug, but that was
+    an incorrect ASSERT, which furthermore was not enabled by default.)
+
+  * A bug affecting 32-bit PowerPC division has been fixed.  The bug caused
+    miscomputation for certain divisors in the range 2^32 ... 2^64-1 (about 1
+    in 2^30 of these).
+
+  SPEEDUPS
+  * None, except indirectly through recognition of new CPUs, and through better
+    tuning parameters.
+
+  FEATURES
+  * Some more tests added to the self-check suite.
+
+  * The AMD "Bulldozer" CPU is now recognised.
+
+  MISC
+  * None.
+
+
 Changes between GMP version 5.0.2 and 5.0.3
 
   BUGS FIXED
diff -ruN gmp-5.0.3/tests/mpn/Makefile.am gmp-5.0.4/tests/mpn/Makefile.am
--- gmp-5.0.3/tests/mpn/Makefile.am	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tests/mpn/Makefile.am	2012-02-10 11:23:05.000000000 +0100
@@ -1,6 +1,6 @@
 ## Process this file with automake to generate Makefile.in
 
-# Copyright 2001, 2002, 2003, 2009, 2010 Free Software Foundation, Inc.
+# Copyright 2001, 2002, 2003, 2009, 2010, 2012 Free Software Foundation, Inc.
 #
 # This file is part of the GNU MP Library.
 #
@@ -21,12 +21,12 @@
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
 LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
 
-check_PROGRAMS = t-asmtype t-aors_1 t-divrem_1 t-fat t-get_d	\
-  t-instrument t-iord_u t-mp_bases t-perfsqr t-scan		\
-  t-toom22 t-toom32 t-toom33 t-toom42 t-toom43 t-toom44 	\
-  t-toom52 t-toom53 t-toom62 t-toom63 t-toom6h t-toom8h		\
-  t-hgcd t-matrix22 t-mullo t-mulmod_bnm1 t-sqrmod_bnm1		\
-  t-invert t-div t-bdiv
+check_PROGRAMS = t-asmtype t-aors_1 t-divrem_1 t-mod_1 t-fat t-get_d	\
+  t-instrument t-iord_u t-mp_bases t-perfsqr t-scan			\
+  t-toom22 t-toom32 t-toom33 t-toom42 t-toom43 t-toom44			\
+  t-toom52 t-toom53 t-toom62 t-toom63 t-toom6h t-toom8h			\
+  t-mul t-mullo t-mulmod_bnm1 t-sqrmod_bnm1				\
+  t-hgcd t-matrix22 t-invert t-div t-bdiv
 
 EXTRA_DIST = toom-shared.h
 
diff -ruN gmp-5.0.3/tests/mpn/Makefile.in gmp-5.0.4/tests/mpn/Makefile.in
--- gmp-5.0.3/tests/mpn/Makefile.in	2012-01-27 09:59:36.000000000 +0100
+++ gmp-5.0.4/tests/mpn/Makefile.in	2012-02-10 11:23:17.000000000 +0100
@@ -15,7 +15,7 @@
 
 @SET_MAKE@
 
-# Copyright 2001, 2002, 2003, 2009, 2010 Free Software Foundation, Inc.
+# Copyright 2001, 2002, 2003, 2009, 2010, 2012 Free Software Foundation, Inc.
 #
 # This file is part of the GNU MP Library.
 #
@@ -52,16 +52,16 @@
 host_triplet = @host@
 ANSI2KNR = $(top_builddir)/ansi2knr
 check_PROGRAMS = t-asmtype$(EXEEXT) t-aors_1$(EXEEXT) \
-	t-divrem_1$(EXEEXT) t-fat$(EXEEXT) t-get_d$(EXEEXT) \
-	t-instrument$(EXEEXT) t-iord_u$(EXEEXT) t-mp_bases$(EXEEXT) \
-	t-perfsqr$(EXEEXT) t-scan$(EXEEXT) t-toom22$(EXEEXT) \
-	t-toom32$(EXEEXT) t-toom33$(EXEEXT) t-toom42$(EXEEXT) \
-	t-toom43$(EXEEXT) t-toom44$(EXEEXT) t-toom52$(EXEEXT) \
-	t-toom53$(EXEEXT) t-toom62$(EXEEXT) t-toom63$(EXEEXT) \
-	t-toom6h$(EXEEXT) t-toom8h$(EXEEXT) t-hgcd$(EXEEXT) \
-	t-matrix22$(EXEEXT) t-mullo$(EXEEXT) t-mulmod_bnm1$(EXEEXT) \
-	t-sqrmod_bnm1$(EXEEXT) t-invert$(EXEEXT) t-div$(EXEEXT) \
-	t-bdiv$(EXEEXT)
+	t-divrem_1$(EXEEXT) t-mod_1$(EXEEXT) t-fat$(EXEEXT) \
+	t-get_d$(EXEEXT) t-instrument$(EXEEXT) t-iord_u$(EXEEXT) \
+	t-mp_bases$(EXEEXT) t-perfsqr$(EXEEXT) t-scan$(EXEEXT) \
+	t-toom22$(EXEEXT) t-toom32$(EXEEXT) t-toom33$(EXEEXT) \
+	t-toom42$(EXEEXT) t-toom43$(EXEEXT) t-toom44$(EXEEXT) \
+	t-toom52$(EXEEXT) t-toom53$(EXEEXT) t-toom62$(EXEEXT) \
+	t-toom63$(EXEEXT) t-toom6h$(EXEEXT) t-toom8h$(EXEEXT) \
+	t-mul$(EXEEXT) t-mullo$(EXEEXT) t-mulmod_bnm1$(EXEEXT) \
+	t-sqrmod_bnm1$(EXEEXT) t-hgcd$(EXEEXT) t-matrix22$(EXEEXT) \
+	t-invert$(EXEEXT) t-div$(EXEEXT) t-bdiv$(EXEEXT)
 subdir = tests/mpn
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -133,11 +133,21 @@
 t_matrix22_LDADD = $(LDADD)
 t_matrix22_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
 	$(top_builddir)/libgmp.la
+t_mod_1_SOURCES = t-mod_1.c
+t_mod_1_OBJECTS = t-mod_1$U.$(OBJEXT)
+t_mod_1_LDADD = $(LDADD)
+t_mod_1_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmp.la
 t_mp_bases_SOURCES = t-mp_bases.c
 t_mp_bases_OBJECTS = t-mp_bases$U.$(OBJEXT)
 t_mp_bases_LDADD = $(LDADD)
 t_mp_bases_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
 	$(top_builddir)/libgmp.la
+t_mul_SOURCES = t-mul.c
+t_mul_OBJECTS = t-mul$U.$(OBJEXT)
+t_mul_LDADD = $(LDADD)
+t_mul_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmp.la
 t_mullo_SOURCES = t-mullo.c
 t_mullo_OBJECTS = t-mullo$U.$(OBJEXT)
 t_mullo_LDADD = $(LDADD)
@@ -237,16 +247,18 @@
 	$(LDFLAGS) -o $@
 SOURCES = t-aors_1.c t-asmtype.c t-bdiv.c t-div.c t-divrem_1.c t-fat.c \
 	t-get_d.c t-hgcd.c t-instrument.c t-invert.c t-iord_u.c \
-	t-matrix22.c t-mp_bases.c t-mullo.c t-mulmod_bnm1.c \
-	t-perfsqr.c t-scan.c t-sqrmod_bnm1.c t-toom22.c t-toom32.c \
-	t-toom33.c t-toom42.c t-toom43.c t-toom44.c t-toom52.c \
-	t-toom53.c t-toom62.c t-toom63.c t-toom6h.c t-toom8h.c
+	t-matrix22.c t-mod_1.c t-mp_bases.c t-mul.c t-mullo.c \
+	t-mulmod_bnm1.c t-perfsqr.c t-scan.c t-sqrmod_bnm1.c \
+	t-toom22.c t-toom32.c t-toom33.c t-toom42.c t-toom43.c \
+	t-toom44.c t-toom52.c t-toom53.c t-toom62.c t-toom63.c \
+	t-toom6h.c t-toom8h.c
 DIST_SOURCES = t-aors_1.c t-asmtype.c t-bdiv.c t-div.c t-divrem_1.c \
 	t-fat.c t-get_d.c t-hgcd.c t-instrument.c t-invert.c \
-	t-iord_u.c t-matrix22.c t-mp_bases.c t-mullo.c t-mulmod_bnm1.c \
-	t-perfsqr.c t-scan.c t-sqrmod_bnm1.c t-toom22.c t-toom32.c \
-	t-toom33.c t-toom42.c t-toom43.c t-toom44.c t-toom52.c \
-	t-toom53.c t-toom62.c t-toom63.c t-toom6h.c t-toom8h.c
+	t-iord_u.c t-matrix22.c t-mod_1.c t-mp_bases.c t-mul.c \
+	t-mullo.c t-mulmod_bnm1.c t-perfsqr.c t-scan.c t-sqrmod_bnm1.c \
+	t-toom22.c t-toom32.c t-toom33.c t-toom42.c t-toom43.c \
+	t-toom44.c t-toom52.c t-toom53.c t-toom62.c t-toom63.c \
+	t-toom6h.c t-toom8h.c
 ETAGS = etags
 CTAGS = ctags
 am__tty_colors = \
@@ -495,9 +507,15 @@
 t-matrix22$(EXEEXT): $(t_matrix22_OBJECTS) $(t_matrix22_DEPENDENCIES) 
 	@rm -f t-matrix22$(EXEEXT)
 	$(LINK) $(t_matrix22_OBJECTS) $(t_matrix22_LDADD) $(LIBS)
+t-mod_1$(EXEEXT): $(t_mod_1_OBJECTS) $(t_mod_1_DEPENDENCIES) 
+	@rm -f t-mod_1$(EXEEXT)
+	$(LINK) $(t_mod_1_OBJECTS) $(t_mod_1_LDADD) $(LIBS)
 t-mp_bases$(EXEEXT): $(t_mp_bases_OBJECTS) $(t_mp_bases_DEPENDENCIES) 
 	@rm -f t-mp_bases$(EXEEXT)
 	$(LINK) $(t_mp_bases_OBJECTS) $(t_mp_bases_LDADD) $(LIBS)
+t-mul$(EXEEXT): $(t_mul_OBJECTS) $(t_mul_DEPENDENCIES) 
+	@rm -f t-mul$(EXEEXT)
+	$(LINK) $(t_mul_OBJECTS) $(t_mul_LDADD) $(LIBS)
 t-mullo$(EXEEXT): $(t_mullo_OBJECTS) $(t_mullo_DEPENDENCIES) 
 	@rm -f t-mullo$(EXEEXT)
 	$(LINK) $(t_mullo_OBJECTS) $(t_mullo_LDADD) $(LIBS)
@@ -593,8 +611,12 @@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-iord_u.c; then echo $(srcdir)/t-iord_u.c; else echo t-iord_u.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 t-matrix22_.c: t-matrix22.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-matrix22.c; then echo $(srcdir)/t-matrix22.c; else echo t-matrix22.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+t-mod_1_.c: t-mod_1.c $(ANSI2KNR)
+	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-mod_1.c; then echo $(srcdir)/t-mod_1.c; else echo t-mod_1.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 t-mp_bases_.c: t-mp_bases.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-mp_bases.c; then echo $(srcdir)/t-mp_bases.c; else echo t-mp_bases.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+t-mul_.c: t-mul.c $(ANSI2KNR)
+	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-mul.c; then echo $(srcdir)/t-mul.c; else echo t-mul.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 t-mullo_.c: t-mullo.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-mullo.c; then echo $(srcdir)/t-mullo.c; else echo t-mullo.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 t-mulmod_bnm1_.c: t-mulmod_bnm1.c $(ANSI2KNR)
@@ -635,7 +657,8 @@
 t-get_d_.$(OBJEXT) t-get_d_.lo t-hgcd_.$(OBJEXT) t-hgcd_.lo \
 t-instrument_.$(OBJEXT) t-instrument_.lo t-invert_.$(OBJEXT) \
 t-invert_.lo t-iord_u_.$(OBJEXT) t-iord_u_.lo t-matrix22_.$(OBJEXT) \
-t-matrix22_.lo t-mp_bases_.$(OBJEXT) t-mp_bases_.lo t-mullo_.$(OBJEXT) \
+t-matrix22_.lo t-mod_1_.$(OBJEXT) t-mod_1_.lo t-mp_bases_.$(OBJEXT) \
+t-mp_bases_.lo t-mul_.$(OBJEXT) t-mul_.lo t-mullo_.$(OBJEXT) \
 t-mullo_.lo t-mulmod_bnm1_.$(OBJEXT) t-mulmod_bnm1_.lo \
 t-perfsqr_.$(OBJEXT) t-perfsqr_.lo t-scan_.$(OBJEXT) t-scan_.lo \
 t-sqrmod_bnm1_.$(OBJEXT) t-sqrmod_bnm1_.lo t-toom22_.$(OBJEXT) \
diff -ruN gmp-5.0.3/tests/mpn/t-hgcd.c gmp-5.0.4/tests/mpn/t-hgcd.c
--- gmp-5.0.3/tests/mpn/t-hgcd.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tests/mpn/t-hgcd.c	2012-02-10 11:23:05.000000000 +0100
@@ -105,9 +105,9 @@
       size_range = mpz_get_ui (bs) % 13 + 2;
 
       mpz_urandomb (bs, rands, size_range);
-      mpz_urandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
+      mpz_rrandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
       mpz_urandomb (bs, rands, size_range);
-      mpz_urandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
+      mpz_rrandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_SIZE);
 
       if (mpz_cmp (op1, op2) < 0)
 	mpz_swap (op1, op2);
diff -ruN gmp-5.0.3/tests/mpn/t-mod_1.c gmp-5.0.4/tests/mpn/t-mod_1.c
--- gmp-5.0.3/tests/mpn/t-mod_1.c	1970-01-01 01:00:00.000000000 +0100
+++ gmp-5.0.4/tests/mpn/t-mod_1.c	2012-02-10 11:23:05.000000000 +0100
@@ -0,0 +1,118 @@
+/* Test mpn_mod_1 variants.
+
+Copyright 2010 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MP Library 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+static void
+check_one (mp_srcptr ap, mp_size_t n, mp_limb_t b)
+{
+  mp_limb_t r_ref = refmpn_mod_1 (ap, n, b);
+  mp_limb_t r;
+
+  if (n >= 2)
+    {
+      mp_limb_t pre[4];
+      mpn_mod_1_1p_cps (pre, b);
+      r = mpn_mod_1_1p (ap, n, b << pre[1], pre);
+      if (r != r_ref)
+	{
+	  printf ("mpn_mod_1_1p failed\n");
+	  goto fail;
+	}
+    }
+  if ((b & GMP_NUMB_HIGHBIT) == 0)
+    {
+      mp_limb_t pre[5];
+      mpn_mod_1s_2p_cps (pre, b);
+      r = mpn_mod_1s_2p (ap, n, b << pre[1], pre);
+      if (r != r_ref)
+	{
+	  printf ("mpn_mod_1s_2p failed\n");
+	  goto fail;
+	}
+    }
+  if (b <= GMP_NUMB_MASK / 4)
+    {
+      mp_limb_t pre[7];
+      mpn_mod_1s_4p_cps (pre, b);
+      r = mpn_mod_1s_4p (ap, n, b << pre[1], pre);
+      if (r != r_ref)
+	{
+	  printf ("mpn_mod_1s_4p failed\n");
+	  goto fail;
+	}
+    }
+  r = mpn_mod_1 (ap, n, b);
+  if (r != r_ref)
+    {
+      printf ("mpn_mod_1 failed\n");
+    fail:
+      printf ("an = %d, a: ", (int) n); mpn_dump (ap, n);
+      printf ("b           : "); mpn_dump (&b, 1);
+      printf ("r (expected): "); mpn_dump (&r_ref, 1);
+      printf ("r (bad)     : "); mpn_dump (&r, 1);
+      abort();
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  gmp_randstate_ptr rands;
+  int i;
+  unsigned a_bits;
+  unsigned b_bits;
+  mpz_t a;
+  mpz_t b;
+
+  tests_start ();
+  rands = RANDS;
+  mpz_init (a);
+  mpz_init (b);
+
+  for (i = 0; i < 300; i++)
+    {
+      mp_size_t asize;
+      a_bits = 1 + gmp_urandomm_ui (rands, 1000);
+      b_bits = 1 + gmp_urandomm_ui (rands, GMP_NUMB_BITS);
+
+      mpz_rrandomb (a, rands, a_bits);
+      mpz_rrandomb (b, rands, b_bits);
+
+      asize = SIZ(a);
+      if (!asize)
+	asize = 1;
+      if (mpz_sgn (b) == 0)
+	mpz_set_ui (b, 1);
+
+      check_one (PTR(a), asize, PTR(b)[0]);
+    }
+
+  mpz_clear (a);
+  mpz_clear (b);
+
+  tests_end ();
+  return 0;
+}
+
diff -ruN gmp-5.0.3/tests/mpn/t-mul.c gmp-5.0.4/tests/mpn/t-mul.c
--- gmp-5.0.3/tests/mpn/t-mul.c	1970-01-01 01:00:00.000000000 +0100
+++ gmp-5.0.4/tests/mpn/t-mul.c	2012-02-10 11:23:05.000000000 +0100
@@ -0,0 +1,101 @@
+/* Test mpn_mul function for all sizes up to a selected limit.
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+The GNU MP Library 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+static unsigned
+isqrt (unsigned t)
+{
+  unsigned s, b;
+
+  for (b = 0, s = t;  b++, s >>= 1; )
+    ;
+
+  s = 1 << (b >> 1);
+  if (b & 1)
+    s += s >> 1;
+
+  do
+    {
+      b = t / s;
+      s = (s + b) >> 1;
+    }
+  while (b < s);
+
+  return s;
+}
+
+int
+main (int argc, char **argv)
+{
+  mp_ptr ap, bp, rp, refp;
+  mp_size_t max_n, an, bn, rn;
+  gmp_randstate_ptr rands;
+  int reps;
+  TMP_DECL;
+  TMP_MARK;
+
+  reps = 1;
+
+  tests_start ();
+  TESTS_REPS (reps, argv, argc);
+
+  rands = RANDS;
+
+  /* Re-interpret reps argument as a size argument.  */
+  max_n = isqrt (reps * 25000);
+
+  ap = TMP_ALLOC_LIMBS (max_n + 1);
+  bp = TMP_ALLOC_LIMBS (max_n + 1);
+  rp = TMP_ALLOC_LIMBS (2 * max_n);
+  refp = TMP_ALLOC_LIMBS (2 * max_n);
+
+  for (an = 1; an <= max_n; an += 1)
+    {
+      for (bn = 1; bn <= an; bn += 1)
+	{
+	  mpn_random2 (ap, an + 1);
+	  mpn_random2 (bp, bn + 1);
+
+	  refmpn_mul (refp, ap, an, bp, bn);
+	  mpn_mul (rp, ap, an, bp, bn);
+
+	  rn = an + bn;
+	  if (mpn_cmp (refp, rp, rn))
+	    {
+	      printf ("ERROR, an = %d, bn = %d, rn = %d\n",
+		      (int) an, (int) bn, (int) rn);
+	      printf ("a: "); mpn_dump (ap, an);
+	      printf ("b: "); mpn_dump (bp, bn);
+	      printf ("r:   "); mpn_dump (rp, rn);
+	      printf ("ref: "); mpn_dump (refp, rn);
+	      abort();
+	    }
+	}
+    }
+  TMP_FREE;
+  tests_end ();
+  return 0;
+}
diff -ruN gmp-5.0.3/tests/mpn/t-toom6h.c gmp-5.0.4/tests/mpn/t-toom6h.c
--- gmp-5.0.3/tests/mpn/t-toom6h.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tests/mpn/t-toom6h.c	2012-02-10 11:23:05.000000000 +0100
@@ -1,9 +1,13 @@
 #define mpn_toomMN_mul mpn_toom6h_mul
 #define mpn_toomMN_mul_itch mpn_toom6h_mul_itch
 
+#define SIZE_LOG 11
+
 /* Smaller sizes not supported; may lead to recursive calls to
    toom22_mul, toom33_mul, or toom44_mul with invalid input size. */
 #define MIN_AN MUL_TOOM6H_THRESHOLD
-#define MIN_BN(an) (MAX ((an*3)>>3, 42) )
+#define MIN_BN(an) (MAX ((an*3)>>3, 46))
+
+#define COUNT 1000
 
 #include "toom-shared.h"
diff -ruN gmp-5.0.3/tests/mpn/t-toom8h.c gmp-5.0.4/tests/mpn/t-toom8h.c
--- gmp-5.0.3/tests/mpn/t-toom8h.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tests/mpn/t-toom8h.c	2012-02-10 11:23:05.000000000 +0100
@@ -1,6 +1,8 @@
 #define mpn_toomMN_mul mpn_toom8h_mul
 #define mpn_toomMN_mul_itch mpn_toom8h_mul_itch
 
+#define SIZE_LOG 11
+
 /* Smaller sizes not supported; may lead to recursive calls to
    toom{22,33,44,6h}_mul with invalid input size. */
 #define MIN_AN MUL_TOOM8H_THRESHOLD
@@ -19,4 +21,6 @@
 #endif
 #endif
 
+#define COUNT 1000
+
 #include "toom-shared.h"
diff -ruN gmp-5.0.3/tests/mpz/t-gcd.c gmp-5.0.4/tests/mpz/t-gcd.c
--- gmp-5.0.3/tests/mpz/t-gcd.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tests/mpz/t-gcd.c	2012-02-10 11:23:05.000000000 +0100
@@ -154,9 +154,9 @@
       size_range = mpz_get_ui (bs) % 17 + 2;
 
       mpz_urandomb (bs, rands, size_range);
-      mpz_urandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
+      mpz_rrandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
       mpz_urandomb (bs, rands, size_range);
-      mpz_urandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
+      mpz_rrandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
 
       mpz_urandomb (bs, rands, 8);
       bsi = mpz_get_ui (bs);
diff -ruN gmp-5.0.3/tests/mpz/t-powm.c gmp-5.0.4/tests/mpz/t-powm.c
--- gmp-5.0.3/tests/mpz/t-powm.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tests/mpz/t-powm.c	2012-02-10 11:23:06.000000000 +0100
@@ -1,6 +1,6 @@
 /* Test mpz_powm, mpz_mul, mpz_mod, mpz_mod_ui, mpz_div_ui.
 
-Copyright 1991, 1993, 1994, 1996, 1999, 2000, 2001, 2009 Free Software
+Copyright 1991, 1993, 1994, 1996, 1999, 2000, 2001, 2009, 2012 Free Software
 Foundation, Inc.
 
 This file is part of the GNU MP Library.
@@ -20,6 +20,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "gmp.h"
 #include "gmp-impl.h"
@@ -27,6 +28,21 @@
 
 void debug_mp __GMP_PROTO ((mpz_t, int));
 
+#define SIZEM 13
+
+/* Check that all sizes up to just above MUL_TOOM22_THRESHOLD have been tested
+   a few times.  FIXME: If SIZEM is set too low, this will never happen.  */
+int
+allsizes_seen (int *allsizes)
+{
+  mp_size_t i;
+
+  for (i = 1; i < MUL_TOOM22_THRESHOLD + 4; i++)
+    if (allsizes[i] < 4)
+      return 0;
+  return 1;
+}
+
 int
 main (int argc, char **argv)
 {
@@ -38,6 +54,7 @@
   gmp_randstate_ptr rands;
   mpz_t bs;
   unsigned long bsi, size_range;
+  unsigned int allsizes[1 << (SIZEM + 2 - 1)];
 
   tests_start ();
   TESTS_REPS (reps, argv, argc);
@@ -55,10 +72,12 @@
   mpz_init (exp2);
   mpz_init (base2);
 
-  for (i = 0; i < reps; i++)
+  memset (allsizes, 0, (1 << (SIZEM + 2 - 1)) * sizeof (int));
+
+  for (i = 0; i < reps || ! allsizes_seen (allsizes); i++)
     {
       mpz_urandomb (bs, rands, 32);
-      size_range = mpz_get_ui (bs) % 13 + 2;
+      size_range = mpz_get_ui (bs) % SIZEM + 2;
 
       do  /* Loop until mathematically well-defined.  */
 	{
@@ -80,6 +99,8 @@
 	}
       while (mpz_cmp_ui (mod, 0) == 0);
 
+      allsizes[SIZ(mod)] += 1;
+
       mpz_urandomb (bs, rands, 2);
       bsi = mpz_get_ui (bs);
       if ((bsi & 1) != 0)
diff -ruN gmp-5.0.3/tests/refmpn.c gmp-5.0.4/tests/refmpn.c
--- gmp-5.0.3/tests/refmpn.c	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tests/refmpn.c	2012-02-10 11:23:06.000000000 +0100
@@ -2,7 +2,7 @@
    of the normal gmp code.  Speed isn't a consideration.
 
 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-2007, 2008, 2009 Free Software Foundation, Inc.
+2007, 2008, 2009, 2012 Free Software Foundation, Inc.
 
 This file is part of the GNU MP Library.
 
diff -ruN gmp-5.0.3/tune/README gmp-5.0.4/tune/README
--- gmp-5.0.3/tune/README	2012-01-27 09:59:30.000000000 +0100
+++ gmp-5.0.4/tune/README	2012-02-10 11:23:06.000000000 +0100
@@ -91,7 +91,7 @@
       LIBS="$old_LIBS"
 
       AC_SUBST(TUNE_LIBS)
-    
+
     might work.
 
 Low resolution timebase
