Update reference toolchain due to some inlining bugs in 4.5.1
Signed-off-by: Stefan Reinauer <stepan@coreboot.org>
Acked-by: Stefan Reinauer <stepan@coreboot.org>



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6195 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc
index 3d8818a..26fbc66 100755
--- a/util/crossgcc/buildgcc
+++ b/util/crossgcc/buildgcc
@@ -18,8 +18,8 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 #
 
-CROSSGCC_DATE="November 16th, 2010"
-CROSSGCC_VERSION="1.02"
+CROSSGCC_DATE="December 16th, 2010"
+CROSSGCC_VERSION="1.03"
 
 # default settings
 TARGETDIR=`pwd`/xgcc
@@ -31,7 +31,7 @@
 MPFR_VERSION=3.0.0
 MPC_VERSION=0.8.2
 LIBELF_VERSION=0.8.13
-GCC_VERSION=4.5.1
+GCC_VERSION=4.5.2
 BINUTILS_VERSION=2.20.1
 GDB_VERSION=7.2
 W32API_VERSION=3.15
@@ -42,7 +42,7 @@
 MPFR_ARCHIVE="http://www.mpfr.org/mpfr-${MPFR_VERSION}/mpfr-${MPFR_VERSION}.tar.bz2"
 MPC_ARCHIVE="http://www.multiprecision.org/mpc/download/mpc-${MPC_VERSION}.tar.gz"
 LIBELF_ARCHIVE="http://www.mr511.de/software/libelf-${LIBELF_VERSION}.tar.gz"
-GCC_ARCHIVE="ftp://ftp.gwdg.de/pub/gnu/ftp/gnu/gcc/gcc-${GCC_VERSION}/gcc-core-${GCC_VERSION}.tar.bz2"
+GCC_ARCHIVE="ftp://ftp.fu-berlin.de/unix/languages/gcc/releases/gcc-${GCC_VERSION}/gcc-core-${GCC_VERSION}.tar.bz2"
 BINUTILS_ARCHIVE="http://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.bz2"
 GDB_ARCHIVE="http://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.bz2"
 W32API_ARCHIVE="http://downloads.sourceforge.net/project/mingw/MinGW/BaseSystem/RuntimeLibrary/Win32-API/w32api-${W32API_VERSION}/w32api-${W32API_VERSION}-mingw32-src.tar.gz"
diff --git a/util/crossgcc/patches/binutils-2.19.1_no-i386-svr4-asm-comments.patch b/util/crossgcc/patches/binutils-2.19.1_no-i386-svr4-asm-comments.patch
deleted file mode 100644
index 07b1d84..0000000
--- a/util/crossgcc/patches/binutils-2.19.1_no-i386-svr4-asm-comments.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- binutils-2.19.1/gas/config/tc-i386.c~	2009-01-20 14:19:04.000000000 +0100
-+++ binutils-2.19.1/gas/config/tc-i386.c	2009-01-20 14:20:47.000000000 +0100
-@@ -318,6 +318,7 @@
- 	 && !defined (TE_GNU)				\
- 	 && !defined (TE_LINUX)				\
-  	 && !defined (TE_NETWARE)			\
-+	 && 0						\
- 	 && !defined (TE_FreeBSD)			\
- 	 && !defined (TE_NetBSD)))
- /* This array holds the chars that always start a comment.  If the
diff --git a/util/crossgcc/patches/gcc-4.4.1_less-junk-in-crtbegin.patch b/util/crossgcc/patches/gcc-4.4.1_less-junk-in-crtbegin.patch
deleted file mode 100644
index 4df9694..0000000
--- a/util/crossgcc/patches/gcc-4.4.1_less-junk-in-crtbegin.patch
+++ /dev/null
@@ -1,50 +0,0 @@
---- t/gcc-4.4.1/gcc/crtstuff.c	Fr. Apr 10 01:23:07 2009
-+++ gcc-4.4.1/gcc/crtstuff.c	Di. Jul 28 16:43:28 2009
-@@ -204,6 +204,7 @@
-   = { (func_ptr) (-1) };
- #endif /* __DTOR_LIST__ alternatives */
-
-+#if 0
- #ifdef USE_EH_FRAME_REGISTRY
- /* Stick a label at the beginning of the frame unwind info so we can register
-    and deregister it with the exception handling library code.  */
-@@ -219,6 +220,7 @@
-   __attribute__ ((unused, section(JCR_SECTION_NAME), aligned(sizeof(void*))))
-   = { };
- #endif /* JCR_SECTION_NAME */
-+#endif
-
- #if defined(INIT_SECTION_ASM_OP) || defined(INIT_ARRAY_SECTION_ASM_OP)
-
-@@ -309,6 +311,7 @@
-   }
- #endif /* !defined(FINI_ARRAY_SECTION_ASM_OP) */
-
-+#if 0
- #ifdef USE_EH_FRAME_REGISTRY
- #ifdef CRT_GET_RFIB_DATA
-   /* If we used the new __register_frame_info_bases interface,
-@@ -320,6 +323,7 @@
-     __deregister_frame_info (__EH_FRAME_BEGIN__);
- #endif
- #endif
-+#endif
-
-   completed = 1;
- }
-@@ -333,6 +337,7 @@
-   = { __do_global_dtors_aux };
- #endif /* !defined(FINI_SECTION_ASM_OP) */
-
-+#if 0
- #if defined(USE_EH_FRAME_REGISTRY) || defined(JCR_SECTION_NAME)
- /* Stick a call to __register_frame_info into the .init section.  For some
-    reason calls with no arguments work more reliably in .init, so stick the
-@@ -364,6 +369,7 @@
-     }
- #endif /* JCR_SECTION_NAME */
- }
-+#endif
-
- #ifdef INIT_SECTION_ASM_OP
- CRT_CALL_STATIC_FUNCTION (INIT_SECTION_ASM_OP, frame_dummy)
diff --git a/util/crossgcc/patches/gcc-4.5.2_pragma.patch b/util/crossgcc/patches/gcc-4.5.2_pragma.patch
new file mode 100644
index 0000000..d36f489
--- /dev/null
+++ b/util/crossgcc/patches/gcc-4.5.2_pragma.patch
@@ -0,0 +1,10 @@
+diff -ur gcc-4.5.2.orig/gcc/config/i386/i386elf.h gcc-4.5.1/gcc/config/i386/i386elf.h
+--- gcc-4.5.2.orig/gcc/config/i386/i386elf.h	2010-11-17 19:48:16.184401200 -0700
++++ gcc-4.5.2/gcc/config/i386/i386elf.h	2010-11-17 20:52:54.443969900 -0700
+@@ -123,3 +123,6 @@
+ #undef ASM_OUTPUT_ALIGNED_BSS
+ #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+   asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
++
++/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop).  */
++#define HANDLE_PRAGMA_PACK_PUSH_POP 1
diff --git a/util/crossgcc/patches/mpfr-3.0.0_allpatches_20101117.patch b/util/crossgcc/patches/mpfr-3.0.0_allpatches_20101216.patch
similarity index 76%
rename from util/crossgcc/patches/mpfr-3.0.0_allpatches_20101117.patch
rename to util/crossgcc/patches/mpfr-3.0.0_allpatches_20101216.patch
index 5bd14b4..2fdcfdd 100644
--- a/util/crossgcc/patches/mpfr-3.0.0_allpatches_20101117.patch
+++ b/util/crossgcc/patches/mpfr-3.0.0_allpatches_20101216.patch
@@ -1,7 +1,227 @@
-diff -rupN mpfr-3.0.0.orig/Makefile.in mpfr-3.0.0/Makefile.in
---- mpfr-3.0.0.orig/Makefile.in	2010-11-17 14:50:50.054040400 -0700
-+++ mpfr-3.0.0/Makefile.in	2010-06-10 05:00:52.000000000 -0600
-@@ -239,6 +239,7 @@ GZIP_ENV = --best
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-06-23 11:02:49.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-06-23 11:03:36.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_out_str
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-06-23 11:03:20.000000000 +0000
+@@ -1 +1 @@
+-3.0.0
++3.0.0-p1
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-06-23 11:03:20.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0"
++#define MPFR_VERSION_STRING "3.0.0-p1"
+ 
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0.orig/mpfr.texi mpfr-3.0.0/mpfr.texi
+--- mpfr-3.0.0.orig/mpfr.texi	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/mpfr.texi	2010-06-23 11:03:12.000000000 +0000
+@@ -2050,7 +2050,7 @@
+ are printed. If @var{base} is greater than 10, @samp{@@} will be used
+ instead of @samp{e} as exponent delimiter.
+ 
+-Return the number of bytes written, or if an error occurred, return 0.
++Return the number of characters written, or if an error occurred, return 0.
+ @end deftypefun
+ 
+ @deftypefun size_t mpfr_inp_str (mpfr_t @var{rop}, FILE *@var{stream}, int @var{base}, mpfr_rnd_t @var{rnd})
+diff -Naurd mpfr-3.0.0.orig/out_str.c mpfr-3.0.0/out_str.c
+--- mpfr-3.0.0.orig/out_str.c	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/out_str.c	2010-06-23 11:03:12.000000000 +0000
+@@ -22,6 +22,16 @@
+ 
+ #include "mpfr-impl.h"
+ 
++/* Warning! S should not contain "%". */
++#define OUT_STR_RET(S)                          \
++  do                                            \
++    {                                           \
++      int r;                                    \
++      r = fprintf (stream, (S));                \
++      return r < 0 ? 0 : r;                     \
++    }                                           \
++  while (0)
++
+ size_t
+ mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op,
+               mpfr_rnd_t rnd_mode)
+@@ -29,6 +39,7 @@
+   char *s, *s0;
+   size_t l;
+   mpfr_exp_t e;
++  int err;
+ 
+   MPFR_ASSERTN (base >= 2 && base <= 62);
+ 
+@@ -36,37 +47,16 @@
+   if (stream == NULL)
+     stream = stdout;
+ 
+-  if (MPFR_IS_NAN(op))
+-    {
+-      fprintf (stream, "@NaN@");
+-      return 3;
+-    }
+-
+-  if (MPFR_IS_INF(op))
+-    {
+-      if (MPFR_SIGN(op) > 0)
+-        {
+-          fprintf (stream, "@Inf@");
+-          return 3;
+-        }
+-      else
+-        {
+-          fprintf (stream, "-@Inf@");
+-          return 4;
+-        }
+-    }
+-
+-  if (MPFR_IS_ZERO(op))
++  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)))
+     {
+-      if (MPFR_SIGN(op) > 0)
+-        {
+-          fprintf(stream, "0");
+-          return 1;
+-        }
++      if (MPFR_IS_NAN (op))
++        OUT_STR_RET ("@NaN@");
++      else if (MPFR_IS_INF (op))
++        OUT_STR_RET (MPFR_IS_POS (op) ? "@Inf@" : "-@Inf@");
+       else
+         {
+-          fprintf(stream, "-0");
+-          return 2;
++          MPFR_ASSERTD (MPFR_IS_ZERO (op));
++          OUT_STR_RET (MPFR_IS_POS (op) ? "0" : "-0");
+         }
+     }
+ 
+@@ -77,21 +67,31 @@
+ 
+   l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str
+                          - may be incorrect, as only an upper bound? */
+-  if (*s == '-')
+-    fputc (*s++, stream);
+ 
+-  /* outputs mantissa */
+-  fputc (*s++, stream); e--; /* leading digit */
+-  fputc ((unsigned char) MPFR_DECIMAL_POINT, stream);
+-  fputs (s, stream);         /* rest of mantissa */
++  /* outputs possible sign and significand */
++  err = (*s == '-' && fputc (*s++, stream) == EOF)
++    || fputc (*s++, stream) == EOF  /* leading digit */
++    || fputc ((unsigned char) MPFR_DECIMAL_POINT, stream) == EOF
++    || fputs (s, stream) == EOF;     /* trailing significand */
+   (*__gmp_free_func) (s0, l);
++  if (MPFR_UNLIKELY (err))
++    return 0;
++
++  e--;  /* due to the leading digit */
+ 
+   /* outputs exponent */
+   if (e)
+     {
++      int r;
++
+       MPFR_ASSERTN(e >= LONG_MIN);
+       MPFR_ASSERTN(e <= LONG_MAX);
+-      l += fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
++
++      r = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
++      if (MPFR_UNLIKELY (r < 0))
++        return 0;
++
++      l += r;
+     }
+ 
+   return l;
+diff -Naurd mpfr-3.0.0.orig/tests/tout_str.c mpfr-3.0.0/tests/tout_str.c
+--- mpfr-3.0.0.orig/tests/tout_str.c	2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0/tests/tout_str.c	2010-06-23 11:03:12.000000000 +0000
+@@ -46,22 +46,54 @@
+ special (void)
+ {
+   mpfr_t x;
++  unsigned int n;
+ 
+   mpfr_init (x);
+ 
+   mpfr_set_nan (x);
+-  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  if (n != 5)
++    {
++      printf ("Error: mpfr_out_str (file, 10, 0, NaN, MPFR_RNDN) wrote %u "
++              "characters instead of 5.\n", n);
++      exit (1);
++    }
+ 
+   mpfr_set_inf (x, 1);
+-  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  if (n != 5)
++    {
++      printf ("Error: mpfr_out_str (file, 10, 0, +Inf, MPFR_RNDN) wrote %u "
++               "characters instead of 5.\n", n);
++      exit (1);
++    }
+ 
+   mpfr_set_inf (x, -1);
+-  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  if (n != 6)
++    {
++      printf ("Error: mpfr_out_str (file, 10, 0, -Inf, MPFR_RNDN) wrote %u "
++               "characters instead of 6.\n", n);
++      exit (1);
++    }
+ 
+   mpfr_set_ui (x, 0, MPFR_RNDN);
+-  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  if (n != 1)
++    {
++      printf ("Error: mpfr_out_str (file, 10, 0, +0, MPFR_RNDN) wrote %u "
++               "characters instead of 1.\n", n);
++      exit (1);
++    }
++
+   mpfr_neg (x, x, MPFR_RNDN);
+-  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
++  if (n != 2)
++    {
++      printf ("Error: mpfr_out_str (file, 10, 0, -0, MPFR_RNDN) wrote %u "
++               "characters instead of 2.\n", n);
++      exit (1);
++    }
+ 
+   mpfr_clear (x);
+ }
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-06-23 11:03:20.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+-  return "3.0.0";
++  return "3.0.0-p1";
+ }
+diff -Naurd mpfr-3.0.0.orig/Makefile.in mpfr-3.0.0/Makefile.in
+--- mpfr-3.0.0.orig/Makefile.in	2010-06-10 11:00:52.000000000 +0000
++++ mpfr-3.0.0/Makefile.in	2010-06-10 11:00:52.000000000 +0000
+@@ -239,6 +239,7 @@
  distuninstallcheck_listfiles = find . -type f -print
  distcleancheck_listfiles = find . -type f -print
  ACLOCAL = @ACLOCAL@
@@ -9,41 +229,34 @@
  AMTAR = @AMTAR@
  AR = @AR@
  AS = @AS@
-diff -rupN mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
---- mpfr-3.0.0.orig/PATCHES	2010-11-17 14:50:50.081041900 -0700
-+++ mpfr-3.0.0/PATCHES	2010-11-17 14:51:05.016295800 -0700
-@@ -0,0 +1,8 @@
-+macros
-+mpfr_set_ld
-+mpfr_sub1
-+tcan_round
-+mpfr_cmp/set_ui/si
-+gamma_underflow
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-06-23 11:03:36.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-06-25 13:23:13.000000000 +0000
+@@ -0,0 +1 @@
 +alloca
-+mpfr_out_str
-diff -rupN mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
---- mpfr-3.0.0.orig/VERSION	2010-11-17 14:50:50.821082000 -0700
-+++ mpfr-3.0.0/VERSION	2010-11-09 08:15:07.000000000 -0700
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-06-23 11:03:20.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-06-25 13:23:13.000000000 +0000
 @@ -1 +1 @@
--3.0.0
-+3.0.0-p8
-diff -rupN mpfr-3.0.0.orig/acinclude.m4 mpfr-3.0.0/acinclude.m4
---- mpfr-3.0.0.orig/acinclude.m4	2010-11-17 14:50:49.896031300 -0700
-+++ mpfr-3.0.0/acinclude.m4	2010-06-10 05:00:14.000000000 -0600
-@@ -59,6 +59,9 @@ AC_CHECK_HEADER([stdarg.h],[AC_DEFINE([H
+-3.0.0-p1
++3.0.0-p2
+diff -Naurd mpfr-3.0.0.orig/acinclude.m4 mpfr-3.0.0/acinclude.m4
+--- mpfr-3.0.0.orig/acinclude.m4	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/acinclude.m4	2010-06-10 11:00:14.000000000 +0000
+@@ -59,6 +59,9 @@
  dnl sys/fpu.h - MIPS specific
  AC_CHECK_HEADERS([sys/time.h sys/fpu.h])
-
+ 
 +dnl Check how to get `alloca'
 +AC_FUNC_ALLOCA
 +
  dnl SIZE_MAX macro
  gl_SIZE_MAX
-
-diff -rupN mpfr-3.0.0.orig/configure mpfr-3.0.0/configure
---- mpfr-3.0.0.orig/configure	2010-11-17 14:50:49.945034100 -0700
-+++ mpfr-3.0.0/configure	2010-06-25 07:23:05.000000000 -0600
-@@ -783,6 +783,7 @@ LIBTOOL
+ 
+diff -Naurd mpfr-3.0.0.orig/configure mpfr-3.0.0/configure
+--- mpfr-3.0.0.orig/configure	2010-06-10 11:00:51.000000000 +0000
++++ mpfr-3.0.0/configure	2010-06-25 13:23:05.000000000 +0000
+@@ -783,6 +783,7 @@
  OBJDUMP
  DLLTOOL
  AS
@@ -51,10 +264,10 @@
  MPFR_LIBM
  ANSI2KNR
  U
-@@ -5622,6 +5623,197 @@ fi
+@@ -5622,6 +5623,197 @@
  done
-
-
+ 
+ 
 +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 +# for constant arguments.  Useless!
 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
@@ -246,10 +459,10 @@
 +fi
 +
 +
-
+ 
    for ac_header in stdint.h
  do :
-@@ -7564,13 +7756,13 @@ if test "${lt_cv_nm_interface+set}" = se
+@@ -7564,13 +7756,13 @@
  else
    lt_cv_nm_interface="BSD nm"
    echo "int some_variable = 0;" > conftest.$ac_ext
@@ -266,7 +479,7 @@
    cat conftest.out >&5
    if $GREP 'External.*some_variable' conftest.out > /dev/null; then
      lt_cv_nm_interface="MS dumpbin"
-@@ -8772,7 +8964,7 @@ ia64-*-hpux*)
+@@ -8772,7 +8964,7 @@
    ;;
  *-*-irix6*)
    # Find out which ABI we are using.
@@ -275,7 +488,7 @@
    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
    (eval $ac_compile) 2>&5
    ac_status=$?
-@@ -10032,11 +10224,11 @@ else
+@@ -10032,11 +10224,11 @@
     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
     -e 's:$: $lt_compiler_flag:'`
@@ -289,7 +502,7 @@
     if (exit $ac_status) && test -s "$ac_outfile"; then
       # The compiler can only warn and ignore the option if not recognized
       # So say no if there are warnings other than the usual output.
-@@ -10371,11 +10563,11 @@ else
+@@ -10371,11 +10563,11 @@
     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
     -e 's:$: $lt_compiler_flag:'`
@@ -303,7 +516,7 @@
     if (exit $ac_status) && test -s "$ac_outfile"; then
       # The compiler can only warn and ignore the option if not recognized
       # So say no if there are warnings other than the usual output.
-@@ -10476,11 +10668,11 @@ else
+@@ -10476,11 +10668,11 @@
     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
     -e 's:$: $lt_compiler_flag:'`
@@ -317,7 +530,7 @@
     if (exit $ac_status) && test -s out/conftest2.$ac_objext
     then
       # The compiler can only warn and ignore the option if not recognized
-@@ -10531,11 +10723,11 @@ else
+@@ -10531,11 +10723,11 @@
     -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
     -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
     -e 's:$: $lt_compiler_flag:'`
@@ -331,28 +544,72 @@
     if (exit $ac_status) && test -s out/conftest2.$ac_objext
     then
       # The compiler can only warn and ignore the option if not recognized
-@@ -12915,7 +13107,7 @@ else
+@@ -12915,7 +13107,7 @@
    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
    lt_status=$lt_dlunknown
    cat > conftest.$ac_ext <<_LT_EOF
 -#line 12918 "configure"
 +#line 13110 "configure"
  #include "confdefs.h"
-
+ 
  #if HAVE_DLFCN_H
-@@ -13011,7 +13203,7 @@ else
+@@ -13011,7 +13203,7 @@
    lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
    lt_status=$lt_dlunknown
    cat > conftest.$ac_ext <<_LT_EOF
 -#line 13014 "configure"
 +#line 13206 "configure"
  #include "confdefs.h"
-
+ 
  #if HAVE_DLFCN_H
-diff -rupN mpfr-3.0.0.orig/gamma.c mpfr-3.0.0/gamma.c
---- mpfr-3.0.0.orig/gamma.c	2010-11-17 14:50:50.003037400 -0700
-+++ mpfr-3.0.0/gamma.c	2010-07-09 18:11:46.000000000 -0600
-@@ -274,7 +274,7 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-06-23 11:03:20.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-06-25 13:23:13.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p1"
++#define MPFR_VERSION_STRING "3.0.0-p2"
+ 
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0.orig/tests/Makefile.in mpfr-3.0.0/tests/Makefile.in
+--- mpfr-3.0.0.orig/tests/Makefile.in	2010-06-10 11:00:52.000000000 +0000
++++ mpfr-3.0.0/tests/Makefile.in	2010-06-10 11:00:52.000000000 +0000
+@@ -960,6 +960,7 @@
+ red=; grn=; lgn=; blu=; std=
+ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ ACLOCAL = @ACLOCAL@
++ALLOCA = @ALLOCA@
+ AMTAR = @AMTAR@
+ AR = @AR@
+ AS = @AS@
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-06-23 11:03:20.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-06-25 13:23:13.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+-  return "3.0.0-p1";
++  return "3.0.0-p2";
+ }
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-07-10 00:11:19.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-07-10 00:12:50.000000000 +0000
+@@ -0,0 +1 @@
++gamma_underflow
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-06-25 13:23:13.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-07-10 00:11:53.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p2
++3.0.0-p3
+diff -Naurd mpfr-3.0.0.orig/gamma.c mpfr-3.0.0/gamma.c
+--- mpfr-3.0.0.orig/gamma.c	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/gamma.c	2010-07-10 00:11:46.000000000 +0000
+@@ -274,7 +274,7 @@
        /* we want an upper bound for x * [log(2-x)-1].
           since x < 0, we need a lower bound on log(2-x) */
        mpfr_ui_sub (xp, 2, x, MPFR_RNDD);
@@ -360,8 +617,8 @@
 +      mpfr_log2 (xp, xp, MPFR_RNDD);
        mpfr_sub_ui (xp, xp, 1, MPFR_RNDD);
        mpfr_mul (xp, xp, x, MPFR_RNDU);
-
-@@ -303,8 +303,8 @@ mpfr_gamma (mpfr_ptr gamma, mpfr_srcptr
+ 
+@@ -303,8 +303,8 @@
          {
            mpfr_sub (tmp, tmp, tmp2, MPFR_RNDZ); /* low bnd on |sin(Pi*(2-x))| */
            mpfr_ui_div (tmp, 12, tmp, MPFR_RNDU); /* upper bound */
@@ -371,79 +628,85 @@
 +          mpfr_add (xp, tmp, xp, MPFR_RNDU);
            underflow = mpfr_cmp_si (xp, expo.saved_emin - 2) <= 0;
          }
-
-diff -rupN mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
---- mpfr-3.0.0.orig/mpfr.h	2010-11-17 14:50:50.066041000 -0700
-+++ mpfr-3.0.0/mpfr.h	2010-11-09 08:15:07.000000000 -0700
-@@ -27,7 +27,7 @@ http://www.gnu.org/licenses/ or write to
+ 
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-06-25 13:23:13.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-07-10 00:11:53.000000000 +0000
+@@ -27,7 +27,7 @@
  #define MPFR_VERSION_MAJOR 3
  #define MPFR_VERSION_MINOR 0
  #define MPFR_VERSION_PATCHLEVEL 0
--#define MPFR_VERSION_STRING "3.0.0"
-+#define MPFR_VERSION_STRING "3.0.0-p8"
-
+-#define MPFR_VERSION_STRING "3.0.0-p2"
++#define MPFR_VERSION_STRING "3.0.0-p3"
+ 
  /* Macros dealing with MPFR VERSION */
  #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
-@@ -67,6 +67,16 @@ MPFR_VERSION_NUM(MPFR_VERSION_MAJOR,MPFR
- # define _MPFR_H_HAVE_INTMAX_T 1
- #endif
-
-+/* Avoid some problems with macro expansion if the user defines macros
-+   with the same name as keywords. By convention, identifiers and macro
-+   names starting with mpfr_ are reserved by MPFR. */
-+typedef void            mpfr_void;
-+typedef int             mpfr_int;
-+typedef unsigned int    mpfr_uint;
-+typedef long            mpfr_long;
-+typedef unsigned long   mpfr_ulong;
-+typedef size_t          mpfr_size_t;
+diff -Naurd mpfr-3.0.0.orig/tests/tgamma.c mpfr-3.0.0/tests/tgamma.c
+--- mpfr-3.0.0.orig/tests/tgamma.c	2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0/tests/tgamma.c	2010-07-10 00:11:46.000000000 +0000
+@@ -461,6 +461,20 @@
+   mpfr_clear (x);
+ }
+ 
++/* bug found by Stathis, only occurs on 32-bit machines */
++static void
++test20100709 (void)
++{
++  mpfr_t x;
++  int inex;
 +
- /* Definition of rounding modes (DON'T USE MPFR_RNDNA!).
-    Warning! Changing the contents of this enum should be seen as an
-    interface change since the old and the new types are not compatible
-@@ -136,7 +146,7 @@ typedef int          mpfr_sign_t;
- typedef mp_exp_t     mpfr_exp_t;
-
- /* Definition of the standard exponent limits */
--#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((unsigned long) 1 << 30) - 1))
-+#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((mpfr_ulong) 1 << 30) - 1))
- #define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT))
-
- /* Definition of the main structure */
-@@ -725,13 +735,13 @@ __MPFR_DECLSPEC int    mpfr_custom_get_k
-    unexpected results with future compilers and aggressive optimisations.
-    Why not working only with signed types, using INT_MIN and LONG_MIN? */
- #if __GMP_MP_SIZE_T_INT
--#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+2))
--#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+1))
--#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+3))
-+#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+2))
-+#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+1))
-+#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+3))
- #else
--#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+2))
--#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+1))
--#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+3))
-+#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+2))
-+#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+1))
-+#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+3))
- #endif
-
- /* Define MPFR_USE_EXTENSION to avoid "gcc -pedantic" warnings. */
-@@ -760,9 +770,9 @@ __MPFR_DECLSPEC int    mpfr_custom_get_k
- #define mpfr_inf_p(_x)      ((_x)->_mpfr_exp == __MPFR_EXP_INF)
- #define mpfr_zero_p(_x)     ((_x)->_mpfr_exp == __MPFR_EXP_ZERO)
- #define mpfr_regular_p(_x)  ((_x)->_mpfr_exp >  __MPFR_EXP_INF)
--#define mpfr_sgn(_x)                                          \
--  ((_x)->_mpfr_exp < __MPFR_EXP_INF ?                         \
--   (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (void) 0), 0 : \
-+#define mpfr_sgn(_x)                                               \
-+  ((_x)->_mpfr_exp < __MPFR_EXP_INF ?                              \
-+   (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : \
-    MPFR_SIGN (_x))
-
- /* Prevent them from using as lvalues */
-@@ -798,50 +808,72 @@ __MPFR_DECLSPEC int    mpfr_custom_get_k
++  mpfr_init2 (x, 100);
++  mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
++  inex = mpfr_gamma (x, x, MPFR_RNDN);
++  MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
++  mpfr_clear (x);
++}
++
+ int
+ main (int argc, char *argv[])
+ {
+@@ -471,6 +485,7 @@
+   test_generic (2, 100, 2);
+   gamma_integer ();
+   test20071231 ();
++  test20100709 ();
+ 
+   data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
+ 
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-06-25 13:23:13.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-07-10 00:11:53.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+-  return "3.0.0-p2";
++  return "3.0.0-p3";
+ }
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-09-07 08:44:01.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-09-07 08:48:46.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_cmp/set_ui/si
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-07-10 00:11:53.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-09-07 08:46:06.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p3
++3.0.0-p4
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-07-10 00:11:53.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-09-07 08:46:06.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p3"
++#define MPFR_VERSION_STRING "3.0.0-p4"
+ 
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+@@ -798,35 +798,45 @@
       anyway. Checking with other ICC versions is needed. Possibly detect
       whether warnings are produced or not with a configure test.
     + Remove C++ too, since it complains too much. */
@@ -454,19 +717,7 @@
 +   Moreover casts to unsigned long have been added to avoid warnings in
 +   programs that use MPFR and are compiled with -Wconversion; such casts
 +   are OK since if X is a constant expression, then (unsigned long) X is
-+   also a constant expression, so that the optimizations still work. The
-+   warnings are probably related to the following two bugs:
-+     http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
-+     http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant)
-+   and the casts could be removed once these bugs are fixed.
-+   Casts shouldn't be used on the generic calls (to the ..._2exp functions),
-+   where implicit conversions are performed. Indeed, having at least one
-+   implicit conversion in the macro allows the compiler to emit diagnostics
-+   when normally expected, for instance in the following call:
-+     mpfr_set_ui (x, "foo", MPFR_RNDN);
-+   If this is not possible (for future macros), one of the tricks described
-+   on http://groups.google.com/group/comp.std.c/msg/e92abd24bf9eaf7b could
-+   be used. */
++   also a constant expression, so that the optimizations still work. */
  #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
  #if (__GNUC__ >= 2)
  #undef mpfr_cmp_ui
@@ -479,17 +730,18 @@
 +   But warning! mpfr_sgn is specified as a macro in the API, thus the macro
 +   mustn't be used if side effects are possible, like here. */
 +#define mpfr_cmp_ui(_f,_u)                                      \
-+  (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ?        \
++  (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ?     \
 +   (mpfr_sgn) (_f) :                                            \
-+   mpfr_cmp_ui_2exp ((_f), (_u), 0))
++   mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0))
  #undef mpfr_cmp_si
 -#define mpfr_cmp_si(_f,_s)                 \
 - (__builtin_constant_p (_s) && (_s) >= 0 ? \
 -   mpfr_cmp_ui ((_f), (_s)) :              \
-+#define mpfr_cmp_si(_f,_s)                                      \
-+  (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ?         \
-+   mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) :          \
-    mpfr_cmp_si_2exp ((_f), (_s), 0))
+-   mpfr_cmp_si_2exp ((_f), (_s), 0))
++#define mpfr_cmp_si(_f,_s)                              \
++  (__builtin_constant_p (_s) && (long) (_s) >= 0 ?      \
++   mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) :    \
++   mpfr_cmp_si_2exp ((_f), (long) (_s), 0))
  #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
  #undef mpfr_set_ui
 -#define mpfr_set_ui(_f,_u,_r)              \
@@ -499,606 +751,35 @@
 -     _p->_mpfr_sign = 1;                   \
 -     _p->_mpfr_exp = __MPFR_EXP_ZERO;      \
 -     (void) (_r); 0; }) :                  \
+-   mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
 +#define mpfr_set_ui(_f,_u,_r)                                   \
-+  (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ?        \
++  (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ?     \
 +   __extension__ ({                                             \
 +       mpfr_ptr _p = (_f);                                      \
 +       _p->_mpfr_sign = 1;                                      \
 +       _p->_mpfr_exp = __MPFR_EXP_ZERO;                         \
-+       (mpfr_void) (_r); 0; }) :                                \
-    mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
++       (void) (_r); 0; }) :                                     \
++   mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r)))
  #endif
  #undef mpfr_set_si
 -#define mpfr_set_si(_f,_s,_r)              \
 - (__builtin_constant_p (_s) && (_s) >= 0 ? \
 -   mpfr_set_ui ((_f), (_s), (_r)) :        \
+-   mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
 +#define mpfr_set_si(_f,_s,_r)                                   \
-+  (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ?         \
-+   mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) :    \
-    mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
++  (__builtin_constant_p (_s) && (long) (_s) >= 0 ?              \
++   mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) :      \
++   mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r)))
  #endif
  #endif
-
- /* Macro version of mpfr_stack interface for fast access */
--#define mpfr_custom_get_size(p) ((size_t)                            \
-+#define mpfr_custom_get_size(p) ((mpfr_size_t)                          \
-        (((p)+GMP_NUMB_BITS-1)/GMP_NUMB_BITS*sizeof (mp_limb_t)))
- #define mpfr_custom_init(m,p) do {} while (0)
--#define mpfr_custom_get_significand(x) ((void*)((x)->_mpfr_d))
-+#define mpfr_custom_get_significand(x) ((mpfr_void*)((x)->_mpfr_d))
- #define mpfr_custom_get_exp(x) ((x)->_mpfr_exp)
- #define mpfr_custom_move(x,m) do { ((x)->_mpfr_d = (mp_limb_t*)(m)); } while (0)
- #define mpfr_custom_init_set(x,k,e,p,m) do {                   \
-   mpfr_ptr _x = (x);                                           \
-   mpfr_exp_t _e;                                               \
-   mpfr_kind_t _t;                                              \
--  int _s, _k;                                                  \
-+  mpfr_int _s, _k;                                             \
-   _k = (k);                                                    \
-   if (_k >= 0)  {                                              \
-     _t = (mpfr_kind_t) _k;                                     \
-@@ -858,11 +890,13 @@ __MPFR_DECLSPEC int    mpfr_custom_get_k
-   _x->_mpfr_exp  = _e;                                         \
-   _x->_mpfr_d    = (mp_limb_t*) (m);                           \
-  } while (0)
--#define mpfr_custom_get_kind(x)                                              \
--  ( (x)->_mpfr_exp >  __MPFR_EXP_INF ? (int)MPFR_REGULAR_KIND*MPFR_SIGN (x) \
--  : (x)->_mpfr_exp == __MPFR_EXP_INF ? (int)MPFR_INF_KIND*MPFR_SIGN (x)     \
--  : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (int)MPFR_NAN_KIND                   \
--  : (int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
-+#define mpfr_custom_get_kind(x)                                         \
-+  ( (x)->_mpfr_exp >  __MPFR_EXP_INF ?                                  \
-+    (mpfr_int) MPFR_REGULAR_KIND * MPFR_SIGN (x)                        \
-+  : (x)->_mpfr_exp == __MPFR_EXP_INF ?                                  \
-+    (mpfr_int) MPFR_INF_KIND * MPFR_SIGN (x)                            \
-+  : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (mpfr_int) MPFR_NAN_KIND         \
-+  : (mpfr_int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
-
-
- #endif /* MPFR_USE_NO_MACRO */
-diff -rupN mpfr-3.0.0.orig/mpfr.texi mpfr-3.0.0/mpfr.texi
---- mpfr-3.0.0.orig/mpfr.texi	2010-11-17 14:50:50.069041200 -0700
-+++ mpfr-3.0.0/mpfr.texi	2010-06-23 05:03:12.000000000 -0600
-@@ -2050,7 +2050,7 @@ first digit and a trailing exponent in b
- are printed. If @var{base} is greater than 10, @samp{@@} will be used
- instead of @samp{e} as exponent delimiter.
-
--Return the number of bytes written, or if an error occurred, return 0.
-+Return the number of characters written, or if an error occurred, return 0.
- @end deftypefun
-
- @deftypefun size_t mpfr_inp_str (mpfr_t @var{rop}, FILE *@var{stream}, int @var{base}, mpfr_rnd_t @var{rnd})
-diff -rupN mpfr-3.0.0.orig/out_str.c mpfr-3.0.0/out_str.c
---- mpfr-3.0.0.orig/out_str.c	2010-11-17 14:50:50.080041800 -0700
-+++ mpfr-3.0.0/out_str.c	2010-06-23 05:03:12.000000000 -0600
-@@ -22,6 +22,16 @@ http://www.gnu.org/licenses/ or write to
-
- #include "mpfr-impl.h"
-
-+/* Warning! S should not contain "%". */
-+#define OUT_STR_RET(S)                          \
-+  do                                            \
-+    {                                           \
-+      int r;                                    \
-+      r = fprintf (stream, (S));                \
-+      return r < 0 ? 0 : r;                     \
-+    }                                           \
-+  while (0)
-+
- size_t
- mpfr_out_str (FILE *stream, int base, size_t n_digits, mpfr_srcptr op,
-               mpfr_rnd_t rnd_mode)
-@@ -29,6 +39,7 @@ mpfr_out_str (FILE *stream, int base, si
-   char *s, *s0;
-   size_t l;
-   mpfr_exp_t e;
-+  int err;
-
-   MPFR_ASSERTN (base >= 2 && base <= 62);
-
-@@ -36,37 +47,16 @@ mpfr_out_str (FILE *stream, int base, si
-   if (stream == NULL)
-     stream = stdout;
-
--  if (MPFR_IS_NAN(op))
--    {
--      fprintf (stream, "@NaN@");
--      return 3;
--    }
--
--  if (MPFR_IS_INF(op))
--    {
--      if (MPFR_SIGN(op) > 0)
--        {
--          fprintf (stream, "@Inf@");
--          return 3;
--        }
--      else
--        {
--          fprintf (stream, "-@Inf@");
--          return 4;
--        }
--    }
--
--  if (MPFR_IS_ZERO(op))
-+  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)))
-     {
--      if (MPFR_SIGN(op) > 0)
--        {
--          fprintf(stream, "0");
--          return 1;
--        }
-+      if (MPFR_IS_NAN (op))
-+        OUT_STR_RET ("@NaN@");
-+      else if (MPFR_IS_INF (op))
-+        OUT_STR_RET (MPFR_IS_POS (op) ? "@Inf@" : "-@Inf@");
-       else
-         {
--          fprintf(stream, "-0");
--          return 2;
-+          MPFR_ASSERTD (MPFR_IS_ZERO (op));
-+          OUT_STR_RET (MPFR_IS_POS (op) ? "0" : "-0");
-         }
-     }
-
-@@ -77,21 +67,31 @@ mpfr_out_str (FILE *stream, int base, si
-
-   l = strlen (s) + 1; /* size of allocated block returned by mpfr_get_str
-                          - may be incorrect, as only an upper bound? */
--  if (*s == '-')
--    fputc (*s++, stream);
-
--  /* outputs mantissa */
--  fputc (*s++, stream); e--; /* leading digit */
--  fputc ((unsigned char) MPFR_DECIMAL_POINT, stream);
--  fputs (s, stream);         /* rest of mantissa */
-+  /* outputs possible sign and significand */
-+  err = (*s == '-' && fputc (*s++, stream) == EOF)
-+    || fputc (*s++, stream) == EOF  /* leading digit */
-+    || fputc ((unsigned char) MPFR_DECIMAL_POINT, stream) == EOF
-+    || fputs (s, stream) == EOF;     /* trailing significand */
-   (*__gmp_free_func) (s0, l);
-+  if (MPFR_UNLIKELY (err))
-+    return 0;
-+
-+  e--;  /* due to the leading digit */
-
-   /* outputs exponent */
-   if (e)
-     {
-+      int r;
-+
-       MPFR_ASSERTN(e >= LONG_MIN);
-       MPFR_ASSERTN(e <= LONG_MAX);
--      l += fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
-+
-+      r = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), (long) e);
-+      if (MPFR_UNLIKELY (r < 0))
-+        return 0;
-+
-+      l += r;
-     }
-
-   return l;
-diff -rupN mpfr-3.0.0.orig/set_ld.c mpfr-3.0.0/set_ld.c
---- mpfr-3.0.0.orig/set_ld.c	2010-11-17 14:50:50.224050100 -0700
-+++ mpfr-3.0.0/set_ld.c	2010-10-21 15:18:26.000000000 -0600
-@@ -102,21 +102,25 @@ mpfr_set_ld (mpfr_ptr r, long double d,
-             {
-               x /= div13; /* exact */
-               shift_exp += 8192;
-+              mpfr_div_2si (t, t, 8192, MPFR_RNDZ);
-             }
-           if (ABS (x) >= div12)
-             {
-               x /= div12; /* exact */
-               shift_exp += 4096;
-+              mpfr_div_2si (t, t, 4096, MPFR_RNDZ);
-             }
-           if (ABS (x) >= div11)
-             {
-               x /= div11; /* exact */
-               shift_exp += 2048;
-+              mpfr_div_2si (t, t, 2048, MPFR_RNDZ);
-             }
-           if (ABS (x) >= div10)
-             {
-               x /= div10; /* exact */
-               shift_exp += 1024;
-+              mpfr_div_2si (t, t, 1024, MPFR_RNDZ);
-             }
-           /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024,
-              therefore we have one extra exponent reduction step */
-@@ -124,9 +128,10 @@ mpfr_set_ld (mpfr_ptr r, long double d,
-             {
-               x /= div9; /* exact */
-               shift_exp += 512;
-+              mpfr_div_2si (t, t, 512, MPFR_RNDZ);
-             }
-         } /* Check overflow of double */
--      else
-+      else /* no overflow on double */
-         {
-           long double div9, div10, div11;
-
-@@ -149,29 +154,34 @@ mpfr_set_ld (mpfr_ptr r, long double d,
-                 {
-                   x /= div13; /* exact */
-                   shift_exp -= 8192;
-+                  mpfr_mul_2si (t, t, 8192, MPFR_RNDZ);
-                 }
-               if (ABS (x) <= div12)
-                 {
-                   x /= div12; /* exact */
-                   shift_exp -= 4096;
-+                  mpfr_mul_2si (t, t, 4096, MPFR_RNDZ);
-                 }
-               if (ABS (x) <= div11)
-                 {
-                   x /= div11; /* exact */
-                   shift_exp -= 2048;
-+                  mpfr_mul_2si (t, t, 2048, MPFR_RNDZ);
-                 }
-               if (ABS (x) <= div10)
-                 {
-                   x /= div10; /* exact */
-                   shift_exp -= 1024;
-+                  mpfr_mul_2si (t, t, 1024, MPFR_RNDZ);
-                 }
-               if (ABS(x) <= div9)
-                 {
-                   x /= div9;  /* exact */
-                   shift_exp -= 512;
-+                  mpfr_mul_2si (t, t, 512, MPFR_RNDZ);
-                 }
-             }
--          else
-+          else /* no underflow */
-             {
-               inexact = mpfr_set_d (u, (double) x, MPFR_RNDZ);
-               MPFR_ASSERTD (inexact == 0);
-diff -rupN mpfr-3.0.0.orig/sub1.c mpfr-3.0.0/sub1.c
---- mpfr-3.0.0.orig/sub1.c	2010-11-17 14:50:50.254051800 -0700
-+++ mpfr-3.0.0/sub1.c	2010-10-21 14:59:32.000000000 -0600
-@@ -37,7 +37,9 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mp
-   mp_size_t cancel2, an, bn, cn, cn0;
-   mp_limb_t *ap, *bp, *cp;
-   mp_limb_t carry, bb, cc, borrow = 0;
--  int inexact, shift_b, shift_c, is_exact = 1, down = 0, add_exp = 0;
-+  int inexact, shift_b, shift_c, add_exp = 0;
-+  int cmp_low = 0; /* used for rounding to nearest: 0 if low(b) = low(c),
-+                      negative if low(b) < low(c), positive if low(b)>low(c) */
-   int sh, k;
-   MPFR_TMP_DECL(marker);
-
-@@ -196,7 +198,8 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mp
-     }
-
- #ifdef DEBUG
--  printf ("shift_b=%d shift_c=%d diffexp=%lu\n", shift_b, shift_c,
-+  printf ("rnd=%s shift_b=%d shift_c=%d diffexp=%lu\n",
-+          mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c,
-           (unsigned long) diff_exp);
- #endif
-
-@@ -307,17 +310,18 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mp
-     {
-       if (MPFR_LIKELY(sh))
-         {
--          is_exact = (carry == 0);
-           /* can decide except when carry = 2^(sh-1) [middle]
-              or carry = 0 [truncate, but cannot decide inexact flag] */
--          down = (carry < (MPFR_LIMB_ONE << (sh - 1)));
-           if (carry > (MPFR_LIMB_ONE << (sh - 1)))
-             goto add_one_ulp;
--          else if ((0 < carry) && down)
-+          else if ((0 < carry) && (carry < (MPFR_LIMB_ONE << (sh - 1))))
-             {
-               inexact = -1; /* result if smaller than exact value */
-               goto truncate;
-             }
-+          /* now carry = 2^(sh-1), in which case cmp_low=2,
-+             or carry = 0, in which case cmp_low=0 */
-+          cmp_low = (carry == 0) ? 0 : 2;
-         }
-     }
-   else /* directed rounding: set rnd_mode to RNDZ iff toward zero */
-@@ -344,12 +348,32 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mp
-   cn -= (long int) an + cancel2;
-
- #ifdef DEBUG
--  printf ("last %d bits from a are %lu, bn=%ld, cn=%ld\n",
-+  printf ("last sh=%d bits from a are %lu, bn=%ld, cn=%ld\n",
-           sh, (unsigned long) carry, (long) bn, (long) cn);
- #endif
-
-+  /* for rounding to nearest, we couldn't conclude up to here in the following
-+     cases:
-+     1. sh = 0, then cmp_low=0: we can either truncate, subtract one ulp
-+        or add one ulp: -1 ulp < low(b)-low(c) < 1 ulp
-+     2. sh > 0 but the low sh bits from high(b)-high(c) equal 2^(sh-1):
-+        -0.5 ulp <= -1/2^sh < low(b)-low(c)-0.5 < 1/2^sh <= 0.5 ulp
-+        we can't decide the rounding, in that case cmp_low=2:
-+        either we truncate and flag=-1, or we add one ulp and flag=1
-+     3. the low sh>0 bits from high(b)-high(c) equal 0: we know we have to
-+        truncate but we can't decide the ternary value, here cmp_low=0:
-+        -0.5 ulp <= -1/2^sh < low(b)-low(c) < 1/2^sh <= 0.5 ulp
-+        we always truncate and inexact can be any of -1,0,1
-+  */
-+
-+  /* note: here cn might exceed cn0, in which case we consider a zero limb */
-   for (k = 0; (bn > 0) || (cn > 0); k = 1)
-     {
-+      /* if cmp_low < 0, we know low(b) - low(c) < 0
-+         if cmp_low > 0, we know low(b) - low(c) > 0
-+            (more precisely if cmp_low = 2, low(b) - low(c) = 0.5 ulp so far)
-+         if cmp_low = 0, so far low(b) - low(c) = 0 */
-+
-       /* get next limbs */
-       bb = (bn > 0) ? bp[--bn] : 0;
-       if ((cn > 0) && (cn-- <= cn0))
-@@ -357,76 +381,115 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mp
-       else
-         cc = 0;
-
--      /* down is set when low(b) < low(c) */
--      if (down == 0)
--        down = (bb < cc);
-+      /* cmp_low compares low(b) and low(c) */
-+      if (cmp_low == 0) /* case 1 or 3 */
-+        cmp_low = (bb < cc) ? -2+k : (bb > cc) ? 1 : 0;
-+
-+      /* Case 1 for k=0 splits into 7 subcases:
-+         1a: bb > cc + half
-+         1b: bb = cc + half
-+         1c: 0 < bb - cc < half
-+         1d: bb = cc
-+         1e: -half < bb - cc < 0
-+         1f: bb - cc = -half
-+         1g: bb - cc < -half
-+
-+         Case 2 splits into 3 subcases:
-+         2a: bb > cc
-+         2b: bb = cc
-+         2c: bb < cc
-+
-+         Case 3 splits into 3 subcases:
-+         3a: bb > cc
-+         3b: bb = cc
-+         3c: bb < cc
-+      */
-
-       /* the case rounding to nearest with sh=0 is special since one couldn't
-          subtract above 1/2 ulp in the trailing limb of the result */
--      if ((rnd_mode == MPFR_RNDN) && sh == 0 && k == 0)
-+      if (rnd_mode == MPFR_RNDN && sh == 0 && k == 0) /* case 1 for k=0 */
-         {
-           mp_limb_t half = MPFR_LIMB_HIGHBIT;
-
--          is_exact = (bb == cc);
--
-           /* add one ulp if bb > cc + half
-              truncate if cc - half < bb < cc + half
-              sub one ulp if bb < cc - half
-           */
-
--          if (down)
-+          if (cmp_low < 0) /* bb < cc: -1 ulp < low(b) - low(c) < 0,
-+                              cases 1e, 1f and 1g */
-             {
-               if (cc >= half)
-                 cc -= half;
--              else
-+              else /* since bb < cc < half, bb+half < 2*half */
-                 bb += half;
-+              /* now we have bb < cc + half:
-+                 we have to subtract one ulp if bb < cc,
-+                 and truncate if bb > cc */
-             }
--          else /* bb >= cc */
-+          else if (cmp_low >= 0) /* bb >= cc, cases 1a to 1d */
-             {
-               if (cc < half)
-                 cc += half;
--              else
-+              else /* since bb >= cc >= half, bb - half >= 0 */
-                 bb -= half;
-+              /* now we have bb > cc - half: we have to add one ulp if bb > cc,
-+                 and truncate if bb < cc */
-+              if (cmp_low > 0)
-+                cmp_low = 2;
-             }
-         }
-
- #ifdef DEBUG
--      printf ("    bb=%lu cc=%lu down=%d is_exact=%d\n",
--              (unsigned long) bb, (unsigned long) cc, down, is_exact);
-+      printf ("k=%u bb=%lu cc=%lu cmp_low=%d\n", k,
-+              (unsigned long) bb, (unsigned long) cc, cmp_low);
- #endif
--      if (bb < cc)
-+      if (cmp_low < 0) /* low(b) - low(c) < 0: either truncate or subtract
-+                          one ulp */
-         {
-           if (rnd_mode == MPFR_RNDZ)
--            goto sub_one_ulp;
-+            goto sub_one_ulp; /* set inexact=-1 */
-           else if (rnd_mode != MPFR_RNDN) /* round away */
-             {
-               inexact = 1;
-               goto truncate;
-             }
--          else /* round to nearest: special case here since for sh=k=0
--                  bb = bb0 - MPFR_LIMB_HIGHBIT */
-+          else /* round to nearest */
-             {
--              if (is_exact && sh == 0)
--                {
--                  /* For k=0 we can't decide exactness since it may depend
--                     from low order bits.
--                     For k=1, the first low limbs matched: low(b)-low(c)<0. */
--                  if (k)
--                    {
--                      inexact = 1;
--                      goto truncate;
--                    }
--                }
--              else if (down && sh == 0)
--                goto sub_one_ulp;
--              else
--                {
--                  inexact = (is_exact) ? 1 : -1;
-+              /* If cmp_low < 0 and bb > cc, then -0.5 ulp < low(b)-low(c) < 0,
-+                 whatever the value of sh.
-+                 If sh>0, then cmp_low < 0 implies that the initial neglected
-+                 sh bits were 0 (otherwise cmp_low=2 initially), thus the
-+                 weight of the new bits is less than 0.5 ulp too.
-+                 If k > 0 (and sh=0) this means that either the first neglected
-+                 limbs bb and cc were equal (thus cmp_low was 0 for k=0),
-+                 or we had bb - cc = -0.5 ulp or 0.5 ulp.
-+                 The last case is not possible here since we would have
-+                 cmp_low > 0 which is sticky.
-+                 In the first case (where we have cmp_low = -1), we truncate,
-+                 whereas in the 2nd case we have cmp_low = -2 and we subtract
-+                 one ulp.
-+              */
-+              if (bb > cc || sh > 0 || cmp_low == -1)
-+                {  /* -0.5 ulp < low(b)-low(c) < 0,
-+                      bb > cc corresponds to cases 1e and 1f1
-+                      sh > 0 corresponds to cases 3c and 3b3
-+                      cmp_low = -1 corresponds to case 1d3 (also 3b3) */
-+                  inexact = 1;
-                   goto truncate;
-                 }
-+              else if (bb < cc) /* here sh = 0 and low(b)-low(c) < -0.5 ulp,
-+                                   this corresponds to cases 1g and 1f3 */
-+                goto sub_one_ulp;
-+              /* the only case where we can't conclude is sh=0 and bb=cc,
-+                 i.e., we have low(b) - low(c) = -0.5 ulp (up to now), thus
-+                 we don't know if we must truncate or subtract one ulp.
-+                 Note: for sh=0 we can't have low(b) - low(c) = -0.5 ulp up to
-+                 now, since low(b) - low(c) > 1/2^sh */
-             }
-         }
--      else if (bb > cc)
-+      else if (cmp_low > 0) /* 0 < low(b) - low(c): either truncate or
-+                               add one ulp */
-         {
-           if (rnd_mode == MPFR_RNDZ)
-             {
-@@ -437,34 +500,70 @@ mpfr_sub1 (mpfr_ptr a, mpfr_srcptr b, mp
-             goto add_one_ulp;
-           else /* round to nearest */
-             {
--              if (is_exact)
-+              if (bb > cc)
-                 {
--                  inexact = -1;
--                  goto truncate;
-+                  /* if sh=0, then bb>cc means that low(b)-low(c) > 0.5 ulp,
-+                     and similarly when cmp_low=2 */
-+                  if (cmp_low == 2) /* cases 1a, 1b1, 2a and 2b1 */
-+                    goto add_one_ulp;
-+                  /* sh > 0 and cmp_low > 0: this implies that the sh initial
-+                     neglected bits were 0, and the remaining low(b)-low(c)>0,
-+                     but its weight is less than 0.5 ulp */
-+                  else /* 0 < low(b) - low(c) < 0.5 ulp, this corresponds to
-+                          cases 3a, 1d1 and 3b1 */
-+                    {
-+                      inexact = -1;
-+                      goto truncate;
-+                    }
-                 }
--              else if (down)
-+              else if (bb < cc) /* 0 < low(b) - low(c) < 0.5 ulp, cases 1c,
-+                                   1b3, 2b3 and 2c */
-                 {
--                  inexact = 1;
-+                  inexact = -1;
-                   goto truncate;
-                 }
--              else
--                goto add_one_ulp;
--            }
--        }
-+              /* the only case where we can't conclude is bb=cc, i.e.,
-+                 low(b) - low(c) = 0.5 ulp (up to now), thus we don't know
-+                 if we must truncate or add one ulp. */
-+            }
-+        }
-+      /* after k=0, we cannot conclude in the following cases, we split them
-+         according to the values of bb and cc for k=1:
-+         1b. sh=0 and cmp_low = 1 and bb-cc = half [around 0.5 ulp]
-+             1b1. bb > cc: add one ulp, inex = 1
-+             1b2: bb = cc: cannot conclude
-+             1b3: bb < cc: truncate, inex = -1
-+         1d. sh=0 and cmp_low = 0 and bb-cc = 0 [around 0]
-+             1d1: bb > cc: truncate, inex = -1
-+             1d2: bb = cc: cannot conclude
-+             1d3: bb < cc: truncate, inex = +1
-+         1f. sh=0 and cmp_low = -1 and bb-cc = -half [around -0.5 ulp]
-+             1f1: bb > cc: truncate, inex = +1
-+             1f2: bb = cc: cannot conclude
-+             1f3: bb < cc: sub one ulp, inex = -1
-+         2b. sh > 0 and cmp_low = 2 and bb=cc [around 0.5 ulp]
-+             2b1. bb > cc: add one ulp, inex = 1
-+             2b2: bb = cc: cannot conclude
-+             2b3: bb < cc: truncate, inex = -1
-+         3b. sh > 0 and cmp_low = 0 [around 0]
-+             3b1. bb > cc: truncate, inex = -1
-+             3b2: bb = cc: cannot conclude
-+             3b3: bb < cc: truncate, inex = +1
-+      */
-     }
-
--  if ((rnd_mode == MPFR_RNDN) && !is_exact)
-+  if ((rnd_mode == MPFR_RNDN) && cmp_low != 0)
-     {
-       /* even rounding rule */
-       if ((ap[0] >> sh) & 1)
-         {
--          if (down)
-+          if (cmp_low < 0)
-             goto sub_one_ulp;
-           else
-             goto add_one_ulp;
-         }
-       else
--        inexact = (down) ? 1 : -1;
-+        inexact = (cmp_low > 0) ? -1 : 1;
-     }
-   else
-     inexact = 0;
-diff -rupN mpfr-3.0.0.orig/tests/Makefile.in mpfr-3.0.0/tests/Makefile.in
---- mpfr-3.0.0.orig/tests/Makefile.in	2010-11-17 14:50:50.267052500 -0700
-+++ mpfr-3.0.0/tests/Makefile.in	2010-06-10 05:00:52.000000000 -0600
-@@ -960,6 +960,7 @@ am__tty_colors = \
- red=; grn=; lgn=; blu=; std=
- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
- ACLOCAL = @ACLOCAL@
-+ALLOCA = @ALLOCA@
- AMTAR = @AMTAR@
- AR = @AR@
- AS = @AS@
-diff -rupN mpfr-3.0.0.orig/tests/tcan_round.c mpfr-3.0.0/tests/tcan_round.c
---- mpfr-3.0.0.orig/tests/tcan_round.c	2010-11-17 14:50:50.414058700 -0700
-+++ mpfr-3.0.0/tests/tcan_round.c	2010-10-21 14:28:38.000000000 -0600
-@@ -41,7 +41,7 @@ check_round_p (void)
-       /* avoid mpn_random which leaks memory */
-       for (i = 0; i < n; i++)
-         buf[i] = randlimb ();
--      p = (mpfr_prec_t) randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
-+      p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
-       err = p + randlimb () % GMP_NUMB_BITS;
-       r1 = mpfr_round_p (buf, n, err, p);
-       r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err,
-diff -rupN mpfr-3.0.0.orig/tests/tcmp_ui.c mpfr-3.0.0/tests/tcmp_ui.c
---- mpfr-3.0.0.orig/tests/tcmp_ui.c	2010-11-17 14:50:50.421059100 -0700
-+++ mpfr-3.0.0/tests/tcmp_ui.c	2010-09-07 02:45:12.000000000 -0600
-@@ -88,6 +88,126 @@ check_nan (void)
+ 
+diff -Naurd mpfr-3.0.0.orig/tests/tcmp_ui.c mpfr-3.0.0/tests/tcmp_ui.c
+--- mpfr-3.0.0.orig/tests/tcmp_ui.c	2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0/tests/tcmp_ui.c	2010-09-07 08:45:12.000000000 +0000
+@@ -88,6 +88,126 @@
    mpfr_clear (x);
  }
-
+ 
 +/* Since mpfr_cmp_ui and mpfr_cmp_si are also implemented by a macro
 +   with __builtin_constant_p for GCC, check that side effects are
 +   handled correctly. */
@@ -1222,22 +903,410 @@
  int
  main (void)
  {
-@@ -216,6 +336,8 @@ main (void)
+@@ -216,6 +336,8 @@
    mpfr_clear (x);
-
+ 
    check_nan ();
 +  check_macros ();
 +  test_macros ();
-
+ 
    tests_end_mpfr ();
    return 0;
-diff -rupN mpfr-3.0.0.orig/tests/tfma.c mpfr-3.0.0/tests/tfma.c
---- mpfr-3.0.0.orig/tests/tfma.c	2010-11-17 14:50:50.701075100 -0700
-+++ mpfr-3.0.0/tests/tfma.c	2010-10-21 14:59:32.000000000 -0600
-@@ -337,6 +337,94 @@ test_underflow2 (void)
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-07-10 00:11:53.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-09-07 08:46:06.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+-  return "3.0.0-p3";
++  return "3.0.0-p4";
+ }
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-10-21 20:28:38.000000000 +0000
+@@ -0,0 +1 @@
++tcan_round
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-09-07 08:46:06.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-10-21 20:28:38.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p4
++3.0.0-p5
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-09-07 08:46:06.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-10-21 20:28:38.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p4"
++#define MPFR_VERSION_STRING "3.0.0-p5"
+ 
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0.orig/tests/tcan_round.c mpfr-3.0.0/tests/tcan_round.c
+--- mpfr-3.0.0.orig/tests/tcan_round.c	2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0/tests/tcan_round.c	2010-10-21 20:28:38.000000000 +0000
+@@ -41,7 +41,7 @@
+       /* avoid mpn_random which leaks memory */
+       for (i = 0; i < n; i++)
+         buf[i] = randlimb ();
+-      p = (mpfr_prec_t) randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
++      p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
+       err = p + randlimb () % GMP_NUMB_BITS;
+       r1 = mpfr_round_p (buf, n, err, p);
+       r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err,
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-09-07 08:46:06.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-10-21 20:28:38.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+-  return "3.0.0-p4";
++  return "3.0.0-p5";
+ }
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-10-21 20:59:32.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_sub1
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-10-21 20:59:32.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p5
++3.0.0-p6
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-10-21 20:59:32.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p5"
++#define MPFR_VERSION_STRING "3.0.0-p6"
+ 
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0.orig/sub1.c mpfr-3.0.0/sub1.c
+--- mpfr-3.0.0.orig/sub1.c	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/sub1.c	2010-10-21 20:59:32.000000000 +0000
+@@ -37,7 +37,9 @@
+   mp_size_t cancel2, an, bn, cn, cn0;
+   mp_limb_t *ap, *bp, *cp;
+   mp_limb_t carry, bb, cc, borrow = 0;
+-  int inexact, shift_b, shift_c, is_exact = 1, down = 0, add_exp = 0;
++  int inexact, shift_b, shift_c, add_exp = 0;
++  int cmp_low = 0; /* used for rounding to nearest: 0 if low(b) = low(c),
++                      negative if low(b) < low(c), positive if low(b)>low(c) */
+   int sh, k;
+   MPFR_TMP_DECL(marker);
+ 
+@@ -196,7 +198,8 @@
+     }
+ 
+ #ifdef DEBUG
+-  printf ("shift_b=%d shift_c=%d diffexp=%lu\n", shift_b, shift_c,
++  printf ("rnd=%s shift_b=%d shift_c=%d diffexp=%lu\n",
++          mpfr_print_rnd_mode (rnd_mode), shift_b, shift_c,
+           (unsigned long) diff_exp);
+ #endif
+ 
+@@ -307,17 +310,18 @@
+     {
+       if (MPFR_LIKELY(sh))
+         {
+-          is_exact = (carry == 0);
+           /* can decide except when carry = 2^(sh-1) [middle]
+              or carry = 0 [truncate, but cannot decide inexact flag] */
+-          down = (carry < (MPFR_LIMB_ONE << (sh - 1)));
+           if (carry > (MPFR_LIMB_ONE << (sh - 1)))
+             goto add_one_ulp;
+-          else if ((0 < carry) && down)
++          else if ((0 < carry) && (carry < (MPFR_LIMB_ONE << (sh - 1))))
+             {
+               inexact = -1; /* result if smaller than exact value */
+               goto truncate;
+             }
++          /* now carry = 2^(sh-1), in which case cmp_low=2,
++             or carry = 0, in which case cmp_low=0 */
++          cmp_low = (carry == 0) ? 0 : 2;
+         }
+     }
+   else /* directed rounding: set rnd_mode to RNDZ iff toward zero */
+@@ -344,12 +348,32 @@
+   cn -= (long int) an + cancel2;
+ 
+ #ifdef DEBUG
+-  printf ("last %d bits from a are %lu, bn=%ld, cn=%ld\n",
++  printf ("last sh=%d bits from a are %lu, bn=%ld, cn=%ld\n",
+           sh, (unsigned long) carry, (long) bn, (long) cn);
+ #endif
+ 
++  /* for rounding to nearest, we couldn't conclude up to here in the following
++     cases:
++     1. sh = 0, then cmp_low=0: we can either truncate, subtract one ulp
++        or add one ulp: -1 ulp < low(b)-low(c) < 1 ulp
++     2. sh > 0 but the low sh bits from high(b)-high(c) equal 2^(sh-1):
++        -0.5 ulp <= -1/2^sh < low(b)-low(c)-0.5 < 1/2^sh <= 0.5 ulp
++        we can't decide the rounding, in that case cmp_low=2:
++        either we truncate and flag=-1, or we add one ulp and flag=1
++     3. the low sh>0 bits from high(b)-high(c) equal 0: we know we have to
++        truncate but we can't decide the ternary value, here cmp_low=0:
++        -0.5 ulp <= -1/2^sh < low(b)-low(c) < 1/2^sh <= 0.5 ulp
++        we always truncate and inexact can be any of -1,0,1
++  */
++
++  /* note: here cn might exceed cn0, in which case we consider a zero limb */
+   for (k = 0; (bn > 0) || (cn > 0); k = 1)
+     {
++      /* if cmp_low < 0, we know low(b) - low(c) < 0
++         if cmp_low > 0, we know low(b) - low(c) > 0
++            (more precisely if cmp_low = 2, low(b) - low(c) = 0.5 ulp so far)
++         if cmp_low = 0, so far low(b) - low(c) = 0 */
++
+       /* get next limbs */
+       bb = (bn > 0) ? bp[--bn] : 0;
+       if ((cn > 0) && (cn-- <= cn0))
+@@ -357,76 +381,115 @@
+       else
+         cc = 0;
+ 
+-      /* down is set when low(b) < low(c) */
+-      if (down == 0)
+-        down = (bb < cc);
++      /* cmp_low compares low(b) and low(c) */
++      if (cmp_low == 0) /* case 1 or 3 */
++        cmp_low = (bb < cc) ? -2+k : (bb > cc) ? 1 : 0;
++
++      /* Case 1 for k=0 splits into 7 subcases:
++         1a: bb > cc + half
++         1b: bb = cc + half
++         1c: 0 < bb - cc < half
++         1d: bb = cc
++         1e: -half < bb - cc < 0
++         1f: bb - cc = -half
++         1g: bb - cc < -half
++
++         Case 2 splits into 3 subcases:
++         2a: bb > cc
++         2b: bb = cc
++         2c: bb < cc
++
++         Case 3 splits into 3 subcases:
++         3a: bb > cc
++         3b: bb = cc
++         3c: bb < cc
++      */
+ 
+       /* the case rounding to nearest with sh=0 is special since one couldn't
+          subtract above 1/2 ulp in the trailing limb of the result */
+-      if ((rnd_mode == MPFR_RNDN) && sh == 0 && k == 0)
++      if (rnd_mode == MPFR_RNDN && sh == 0 && k == 0) /* case 1 for k=0 */
+         {
+           mp_limb_t half = MPFR_LIMB_HIGHBIT;
+ 
+-          is_exact = (bb == cc);
+-
+           /* add one ulp if bb > cc + half
+              truncate if cc - half < bb < cc + half
+              sub one ulp if bb < cc - half
+           */
+ 
+-          if (down)
++          if (cmp_low < 0) /* bb < cc: -1 ulp < low(b) - low(c) < 0,
++                              cases 1e, 1f and 1g */
+             {
+               if (cc >= half)
+                 cc -= half;
+-              else
++              else /* since bb < cc < half, bb+half < 2*half */
+                 bb += half;
++              /* now we have bb < cc + half:
++                 we have to subtract one ulp if bb < cc,
++                 and truncate if bb > cc */
+             }
+-          else /* bb >= cc */
++          else if (cmp_low >= 0) /* bb >= cc, cases 1a to 1d */
+             {
+               if (cc < half)
+                 cc += half;
+-              else
++              else /* since bb >= cc >= half, bb - half >= 0 */
+                 bb -= half;
++              /* now we have bb > cc - half: we have to add one ulp if bb > cc,
++                 and truncate if bb < cc */
++              if (cmp_low > 0)
++                cmp_low = 2;
+             }
+         }
+ 
+ #ifdef DEBUG
+-      printf ("    bb=%lu cc=%lu down=%d is_exact=%d\n",
+-              (unsigned long) bb, (unsigned long) cc, down, is_exact);
++      printf ("k=%u bb=%lu cc=%lu cmp_low=%d\n", k,
++              (unsigned long) bb, (unsigned long) cc, cmp_low);
+ #endif
+-      if (bb < cc)
++      if (cmp_low < 0) /* low(b) - low(c) < 0: either truncate or subtract
++                          one ulp */
+         {
+           if (rnd_mode == MPFR_RNDZ)
+-            goto sub_one_ulp;
++            goto sub_one_ulp; /* set inexact=-1 */
+           else if (rnd_mode != MPFR_RNDN) /* round away */
+             {
+               inexact = 1;
+               goto truncate;
+             }
+-          else /* round to nearest: special case here since for sh=k=0
+-                  bb = bb0 - MPFR_LIMB_HIGHBIT */
++          else /* round to nearest */
+             {
+-              if (is_exact && sh == 0)
+-                {
+-                  /* For k=0 we can't decide exactness since it may depend
+-                     from low order bits.
+-                     For k=1, the first low limbs matched: low(b)-low(c)<0. */
+-                  if (k)
+-                    {
+-                      inexact = 1;
+-                      goto truncate;
+-                    }
+-                }
+-              else if (down && sh == 0)
+-                goto sub_one_ulp;
+-              else
+-                {
+-                  inexact = (is_exact) ? 1 : -1;
++              /* If cmp_low < 0 and bb > cc, then -0.5 ulp < low(b)-low(c) < 0,
++                 whatever the value of sh.
++                 If sh>0, then cmp_low < 0 implies that the initial neglected
++                 sh bits were 0 (otherwise cmp_low=2 initially), thus the
++                 weight of the new bits is less than 0.5 ulp too.
++                 If k > 0 (and sh=0) this means that either the first neglected
++                 limbs bb and cc were equal (thus cmp_low was 0 for k=0),
++                 or we had bb - cc = -0.5 ulp or 0.5 ulp.
++                 The last case is not possible here since we would have
++                 cmp_low > 0 which is sticky.
++                 In the first case (where we have cmp_low = -1), we truncate,
++                 whereas in the 2nd case we have cmp_low = -2 and we subtract
++                 one ulp.
++              */
++              if (bb > cc || sh > 0 || cmp_low == -1)
++                {  /* -0.5 ulp < low(b)-low(c) < 0,
++                      bb > cc corresponds to cases 1e and 1f1
++                      sh > 0 corresponds to cases 3c and 3b3
++                      cmp_low = -1 corresponds to case 1d3 (also 3b3) */
++                  inexact = 1;
+                   goto truncate;
+                 }
++              else if (bb < cc) /* here sh = 0 and low(b)-low(c) < -0.5 ulp,
++                                   this corresponds to cases 1g and 1f3 */
++                goto sub_one_ulp;
++              /* the only case where we can't conclude is sh=0 and bb=cc,
++                 i.e., we have low(b) - low(c) = -0.5 ulp (up to now), thus
++                 we don't know if we must truncate or subtract one ulp.
++                 Note: for sh=0 we can't have low(b) - low(c) = -0.5 ulp up to
++                 now, since low(b) - low(c) > 1/2^sh */
+             }
+         }
+-      else if (bb > cc)
++      else if (cmp_low > 0) /* 0 < low(b) - low(c): either truncate or
++                               add one ulp */
+         {
+           if (rnd_mode == MPFR_RNDZ)
+             {
+@@ -437,34 +500,70 @@
+             goto add_one_ulp;
+           else /* round to nearest */
+             {
+-              if (is_exact)
++              if (bb > cc)
+                 {
+-                  inexact = -1;
+-                  goto truncate;
++                  /* if sh=0, then bb>cc means that low(b)-low(c) > 0.5 ulp,
++                     and similarly when cmp_low=2 */
++                  if (cmp_low == 2) /* cases 1a, 1b1, 2a and 2b1 */
++                    goto add_one_ulp;
++                  /* sh > 0 and cmp_low > 0: this implies that the sh initial
++                     neglected bits were 0, and the remaining low(b)-low(c)>0,
++                     but its weight is less than 0.5 ulp */
++                  else /* 0 < low(b) - low(c) < 0.5 ulp, this corresponds to
++                          cases 3a, 1d1 and 3b1 */
++                    {
++                      inexact = -1;
++                      goto truncate;
++                    }
+                 }
+-              else if (down)
++              else if (bb < cc) /* 0 < low(b) - low(c) < 0.5 ulp, cases 1c,
++                                   1b3, 2b3 and 2c */
+                 {
+-                  inexact = 1;
++                  inexact = -1;
+                   goto truncate;
+                 }
+-              else
+-                goto add_one_ulp;
++              /* the only case where we can't conclude is bb=cc, i.e.,
++                 low(b) - low(c) = 0.5 ulp (up to now), thus we don't know
++                 if we must truncate or add one ulp. */
+             }
+         }
++      /* after k=0, we cannot conclude in the following cases, we split them
++         according to the values of bb and cc for k=1:
++         1b. sh=0 and cmp_low = 1 and bb-cc = half [around 0.5 ulp]
++             1b1. bb > cc: add one ulp, inex = 1
++             1b2: bb = cc: cannot conclude
++             1b3: bb < cc: truncate, inex = -1
++         1d. sh=0 and cmp_low = 0 and bb-cc = 0 [around 0]
++             1d1: bb > cc: truncate, inex = -1
++             1d2: bb = cc: cannot conclude
++             1d3: bb < cc: truncate, inex = +1
++         1f. sh=0 and cmp_low = -1 and bb-cc = -half [around -0.5 ulp]
++             1f1: bb > cc: truncate, inex = +1
++             1f2: bb = cc: cannot conclude
++             1f3: bb < cc: sub one ulp, inex = -1
++         2b. sh > 0 and cmp_low = 2 and bb=cc [around 0.5 ulp]
++             2b1. bb > cc: add one ulp, inex = 1
++             2b2: bb = cc: cannot conclude
++             2b3: bb < cc: truncate, inex = -1
++         3b. sh > 0 and cmp_low = 0 [around 0]
++             3b1. bb > cc: truncate, inex = -1
++             3b2: bb = cc: cannot conclude
++             3b3: bb < cc: truncate, inex = +1
++      */
+     }
+ 
+-  if ((rnd_mode == MPFR_RNDN) && !is_exact)
++  if ((rnd_mode == MPFR_RNDN) && cmp_low != 0)
+     {
+       /* even rounding rule */
+       if ((ap[0] >> sh) & 1)
+         {
+-          if (down)
++          if (cmp_low < 0)
+             goto sub_one_ulp;
+           else
+             goto add_one_ulp;
+         }
+       else
+-        inexact = (down) ? 1 : -1;
++        inexact = (cmp_low > 0) ? -1 : 1;
+     }
+   else
+     inexact = 0;
+diff -Naurd mpfr-3.0.0.orig/tests/tfma.c mpfr-3.0.0/tests/tfma.c
+--- mpfr-3.0.0.orig/tests/tfma.c	2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0/tests/tfma.c	2010-10-21 20:59:32.000000000 +0000
+@@ -337,6 +337,94 @@
    mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
  }
-
+ 
 +static void
 +bug20101018 (void)
 +{
@@ -1329,159 +1398,19 @@
  int
  main (int argc, char *argv[])
  {
-@@ -345,6 +433,8 @@ main (int argc, char *argv[])
-
+@@ -345,6 +433,8 @@
+ 
    tests_start_mpfr ();
-
+ 
 +  bug20101018 ();
 +
    mpfr_init (x);
    mpfr_init (s);
    mpfr_init (y);
-diff -rupN mpfr-3.0.0.orig/tests/tgamma.c mpfr-3.0.0/tests/tgamma.c
---- mpfr-3.0.0.orig/tests/tgamma.c	2010-11-17 14:50:50.706075400 -0700
-+++ mpfr-3.0.0/tests/tgamma.c	2010-07-09 18:11:46.000000000 -0600
-@@ -461,6 +461,20 @@ test20071231 (void)
-   mpfr_clear (x);
- }
-
-+/* bug found by Stathis, only occurs on 32-bit machines */
-+static void
-+test20100709 (void)
-+{
-+  mpfr_t x;
-+  int inex;
-+
-+  mpfr_init2 (x, 100);
-+  mpfr_set_str (x, "-4.6308260837372266e+07", 10, MPFR_RNDN);
-+  inex = mpfr_gamma (x, x, MPFR_RNDN);
-+  MPFR_ASSERTN(MPFR_IS_ZERO(x) && MPFR_IS_NEG(x) && inex > 0);
-+  mpfr_clear (x);
-+}
-+
- int
- main (int argc, char *argv[])
- {
-@@ -471,6 +485,7 @@ main (int argc, char *argv[])
-   test_generic (2, 100, 2);
-   gamma_integer ();
-   test20071231 ();
-+  test20100709 ();
-
-   data_check ("data/gamma", mpfr_gamma, "mpfr_gamma");
-
-diff -rupN mpfr-3.0.0.orig/tests/tout_str.c mpfr-3.0.0/tests/tout_str.c
---- mpfr-3.0.0.orig/tests/tout_str.c	2010-11-17 14:50:50.753078100 -0700
-+++ mpfr-3.0.0/tests/tout_str.c	2010-06-23 05:03:12.000000000 -0600
-@@ -46,22 +46,54 @@ static void
- special (void)
- {
-   mpfr_t x;
-+  unsigned int n;
-
-   mpfr_init (x);
-
-   mpfr_set_nan (x);
--  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  if (n != 5)
-+    {
-+      printf ("Error: mpfr_out_str (file, 10, 0, NaN, MPFR_RNDN) wrote %u "
-+              "characters instead of 5.\n", n);
-+      exit (1);
-+    }
-
-   mpfr_set_inf (x, 1);
--  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  if (n != 5)
-+    {
-+      printf ("Error: mpfr_out_str (file, 10, 0, +Inf, MPFR_RNDN) wrote %u "
-+               "characters instead of 5.\n", n);
-+      exit (1);
-+    }
-
-   mpfr_set_inf (x, -1);
--  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  if (n != 6)
-+    {
-+      printf ("Error: mpfr_out_str (file, 10, 0, -Inf, MPFR_RNDN) wrote %u "
-+               "characters instead of 6.\n", n);
-+      exit (1);
-+    }
-
-   mpfr_set_ui (x, 0, MPFR_RNDN);
--  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  if (n != 1)
-+    {
-+      printf ("Error: mpfr_out_str (file, 10, 0, +0, MPFR_RNDN) wrote %u "
-+               "characters instead of 1.\n", n);
-+      exit (1);
-+    }
-+
-   mpfr_neg (x, x, MPFR_RNDN);
--  mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  n = mpfr_out_str (fout, 10, 0, x, MPFR_RNDN);
-+  if (n != 2)
-+    {
-+      printf ("Error: mpfr_out_str (file, 10, 0, -0, MPFR_RNDN) wrote %u "
-+               "characters instead of 2.\n", n);
-+      exit (1);
-+    }
-
-   mpfr_clear (x);
- }
-diff -rupN mpfr-3.0.0.orig/tests/tset_ld.c mpfr-3.0.0/tests/tset_ld.c
---- mpfr-3.0.0.orig/tests/tset_ld.c	2010-11-17 14:50:50.773079300 -0700
-+++ mpfr-3.0.0/tests/tset_ld.c	2010-10-21 15:18:26.000000000 -0600
-@@ -147,12 +147,39 @@ static void
- test_fixed_bugs (void)
- {
-   mpfr_t x;
--  long double d;
-+  long double l, m;
-
-   /* bug found by Steve Kargl (2009-03-14) */
-   mpfr_init2 (x, 64);
-   mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN);
--  d = mpfr_get_ld (x, MPFR_RNDN);  /* an assertion failed in init2.c:50 */
-+  mpfr_get_ld (x, MPFR_RNDN);  /* an assertion failed in init2.c:50 */
-+
-+  /* bug reported by Jakub Jelinek (2010-10-17)
-+     https://gforge.inria.fr/tracker/?func=detail&aid=11300 */
-+  mpfr_set_prec (x, MPFR_LDBL_MANT_DIG);
-+  /* l = 0x1.23456789abcdef0123456789abcdp-914L; */
-+  l = 8.215640181713713164092636634579e-276;
-+  mpfr_set_ld (x, l, MPFR_RNDN);
-+  m = mpfr_get_ld (x, MPFR_RNDN);
-+  if (m != l)
-+    {
-+      printf ("Error in get_ld o set_ld for l=%Le\n", l);
-+      printf ("Got m=%Le instead of l\n", m);
-+      exit (1);
-+    }
-+
-+  /* another similar test which failed with extended double precision and the
-+     generic code for mpfr_set_ld */
-+  /* l = 0x1.23456789abcdef0123456789abcdp-968L; */
-+  l = 4.560596445887084662336528403703e-292;
-+  mpfr_set_ld (x, l, MPFR_RNDN);
-+  m = mpfr_get_ld (x, MPFR_RNDN);
-+  if (m != l)
-+    {
-+      printf ("Error in get_ld o set_ld for l=%Le\n", l);
-+      printf ("Got m=%Le instead of l\n", m);
-+      exit (1);
-+    }
-
-   mpfr_clear (x);
- }
-diff -rupN mpfr-3.0.0.orig/tests/tsub.c mpfr-3.0.0/tests/tsub.c
---- mpfr-3.0.0.orig/tests/tsub.c	2010-11-17 14:50:50.791080300 -0700
-+++ mpfr-3.0.0/tests/tsub.c	2010-10-21 14:59:32.000000000 -0600
-@@ -201,6 +201,8 @@ check_diverse (void)
+diff -Naurd mpfr-3.0.0.orig/tests/tsub.c mpfr-3.0.0/tests/tsub.c
+--- mpfr-3.0.0.orig/tests/tsub.c	2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0/tests/tsub.c	2010-10-21 20:59:32.000000000 +0000
+@@ -201,6 +201,8 @@
    if (mpfr_cmp (z, x))
      {
        printf ("Error in mpfr_sub (2)\n");
@@ -1490,10 +1419,10 @@
        exit (1);
      }
    mpfr_set_str_binary (x, "1.1110111011110001110111011111111111101000011001011100101100101101");
-@@ -478,6 +480,156 @@ check_inexact (void)
+@@ -478,6 +480,156 @@
    mpfr_clear (u);
  }
-
+ 
 +/* Bug found by Jakub Jelinek
 + * http://bugzilla.redhat.com/643657
 + * https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301
@@ -1647,22 +1576,370 @@
  #define TEST_FUNCTION test_sub
  #define TWO_ARGS
  #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
-@@ -491,6 +643,8 @@ main (void)
-
+@@ -491,6 +643,8 @@
+ 
    tests_start_mpfr ();
-
+ 
 +  bug20101017 ();
 +  check_rounding ();
    check_diverse ();
    check_inexact ();
    bug_ddefour ();
-diff -rupN mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
---- mpfr-3.0.0.orig/version.c	2010-11-17 14:50:50.822082100 -0700
-+++ mpfr-3.0.0/version.c	2010-11-09 08:15:07.000000000 -0700
-@@ -25,5 +25,5 @@ http://www.gnu.org/licenses/ or write to
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-10-21 20:28:38.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-10-21 20:59:32.000000000 +0000
+@@ -25,5 +25,5 @@
  const char *
  mpfr_get_version (void)
  {
--  return "3.0.0";
+-  return "3.0.0-p5";
++  return "3.0.0-p6";
+ }
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-10-21 21:18:26.000000000 +0000
+@@ -0,0 +1 @@
++mpfr_set_ld
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-10-21 21:18:26.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p6
++3.0.0-p7
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-10-21 21:18:26.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p6"
++#define MPFR_VERSION_STRING "3.0.0-p7"
+ 
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+diff -Naurd mpfr-3.0.0.orig/set_ld.c mpfr-3.0.0/set_ld.c
+--- mpfr-3.0.0.orig/set_ld.c	2010-06-10 11:00:14.000000000 +0000
++++ mpfr-3.0.0/set_ld.c	2010-10-21 21:18:26.000000000 +0000
+@@ -102,21 +102,25 @@
+             {
+               x /= div13; /* exact */
+               shift_exp += 8192;
++              mpfr_div_2si (t, t, 8192, MPFR_RNDZ);
+             }
+           if (ABS (x) >= div12)
+             {
+               x /= div12; /* exact */
+               shift_exp += 4096;
++              mpfr_div_2si (t, t, 4096, MPFR_RNDZ);
+             }
+           if (ABS (x) >= div11)
+             {
+               x /= div11; /* exact */
+               shift_exp += 2048;
++              mpfr_div_2si (t, t, 2048, MPFR_RNDZ);
+             }
+           if (ABS (x) >= div10)
+             {
+               x /= div10; /* exact */
+               shift_exp += 1024;
++              mpfr_div_2si (t, t, 1024, MPFR_RNDZ);
+             }
+           /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024,
+              therefore we have one extra exponent reduction step */
+@@ -124,9 +128,10 @@
+             {
+               x /= div9; /* exact */
+               shift_exp += 512;
++              mpfr_div_2si (t, t, 512, MPFR_RNDZ);
+             }
+         } /* Check overflow of double */
+-      else
++      else /* no overflow on double */
+         {
+           long double div9, div10, div11;
+ 
+@@ -149,29 +154,34 @@
+                 {
+                   x /= div13; /* exact */
+                   shift_exp -= 8192;
++                  mpfr_mul_2si (t, t, 8192, MPFR_RNDZ);
+                 }
+               if (ABS (x) <= div12)
+                 {
+                   x /= div12; /* exact */
+                   shift_exp -= 4096;
++                  mpfr_mul_2si (t, t, 4096, MPFR_RNDZ);
+                 }
+               if (ABS (x) <= div11)
+                 {
+                   x /= div11; /* exact */
+                   shift_exp -= 2048;
++                  mpfr_mul_2si (t, t, 2048, MPFR_RNDZ);
+                 }
+               if (ABS (x) <= div10)
+                 {
+                   x /= div10; /* exact */
+                   shift_exp -= 1024;
++                  mpfr_mul_2si (t, t, 1024, MPFR_RNDZ);
+                 }
+               if (ABS(x) <= div9)
+                 {
+                   x /= div9;  /* exact */
+                   shift_exp -= 512;
++                  mpfr_mul_2si (t, t, 512, MPFR_RNDZ);
+                 }
+             }
+-          else
++          else /* no underflow */
+             {
+               inexact = mpfr_set_d (u, (double) x, MPFR_RNDZ);
+               MPFR_ASSERTD (inexact == 0);
+diff -Naurd mpfr-3.0.0.orig/tests/tset_ld.c mpfr-3.0.0/tests/tset_ld.c
+--- mpfr-3.0.0.orig/tests/tset_ld.c	2010-06-10 11:00:13.000000000 +0000
++++ mpfr-3.0.0/tests/tset_ld.c	2010-10-21 21:18:26.000000000 +0000
+@@ -147,12 +147,39 @@
+ test_fixed_bugs (void)
+ {
+   mpfr_t x;
+-  long double d;
++  long double l, m;
+ 
+   /* bug found by Steve Kargl (2009-03-14) */
+   mpfr_init2 (x, 64);
+   mpfr_set_ui_2exp (x, 1, -16447, MPFR_RNDN);
+-  d = mpfr_get_ld (x, MPFR_RNDN);  /* an assertion failed in init2.c:50 */
++  mpfr_get_ld (x, MPFR_RNDN);  /* an assertion failed in init2.c:50 */
++
++  /* bug reported by Jakub Jelinek (2010-10-17)
++     https://gforge.inria.fr/tracker/?func=detail&aid=11300 */
++  mpfr_set_prec (x, MPFR_LDBL_MANT_DIG);
++  /* l = 0x1.23456789abcdef0123456789abcdp-914L; */
++  l = 8.215640181713713164092636634579e-276;
++  mpfr_set_ld (x, l, MPFR_RNDN);
++  m = mpfr_get_ld (x, MPFR_RNDN);
++  if (m != l)
++    {
++      printf ("Error in get_ld o set_ld for l=%Le\n", l);
++      printf ("Got m=%Le instead of l\n", m);
++      exit (1);
++    }
++
++  /* another similar test which failed with extended double precision and the
++     generic code for mpfr_set_ld */
++  /* l = 0x1.23456789abcdef0123456789abcdp-968L; */
++  l = 4.560596445887084662336528403703e-292;
++  mpfr_set_ld (x, l, MPFR_RNDN);
++  m = mpfr_get_ld (x, MPFR_RNDN);
++  if (m != l)
++    {
++      printf ("Error in get_ld o set_ld for l=%Le\n", l);
++      printf ("Got m=%Le instead of l\n", m);
++      exit (1);
++    }
+ 
+   mpfr_clear (x);
+ }
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-10-21 20:59:32.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-10-21 21:18:26.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+-  return "3.0.0-p6";
++  return "3.0.0-p7";
+ }
+diff -Naurd mpfr-3.0.0.orig/PATCHES mpfr-3.0.0/PATCHES
+--- mpfr-3.0.0.orig/PATCHES	2010-11-09 15:15:07.000000000 +0000
++++ mpfr-3.0.0/PATCHES	2010-11-09 15:15:07.000000000 +0000
+@@ -0,0 +1 @@
++macros
+diff -Naurd mpfr-3.0.0.orig/VERSION mpfr-3.0.0/VERSION
+--- mpfr-3.0.0.orig/VERSION	2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0/VERSION	2010-11-09 15:15:07.000000000 +0000
+@@ -1 +1 @@
+-3.0.0-p7
++3.0.0-p8
+diff -Naurd mpfr-3.0.0.orig/mpfr.h mpfr-3.0.0/mpfr.h
+--- mpfr-3.0.0.orig/mpfr.h	2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0/mpfr.h	2010-11-09 15:15:07.000000000 +0000
+@@ -27,7 +27,7 @@
+ #define MPFR_VERSION_MAJOR 3
+ #define MPFR_VERSION_MINOR 0
+ #define MPFR_VERSION_PATCHLEVEL 0
+-#define MPFR_VERSION_STRING "3.0.0-p7"
++#define MPFR_VERSION_STRING "3.0.0-p8"
+ 
+ /* Macros dealing with MPFR VERSION */
+ #define MPFR_VERSION_NUM(a,b,c) (((a) << 16L) | ((b) << 8) | (c))
+@@ -67,6 +67,16 @@
+ # define _MPFR_H_HAVE_INTMAX_T 1
+ #endif
+ 
++/* Avoid some problems with macro expansion if the user defines macros
++   with the same name as keywords. By convention, identifiers and macro
++   names starting with mpfr_ are reserved by MPFR. */
++typedef void            mpfr_void;
++typedef int             mpfr_int;
++typedef unsigned int    mpfr_uint;
++typedef long            mpfr_long;
++typedef unsigned long   mpfr_ulong;
++typedef size_t          mpfr_size_t;
++
+ /* Definition of rounding modes (DON'T USE MPFR_RNDNA!).
+    Warning! Changing the contents of this enum should be seen as an
+    interface change since the old and the new types are not compatible
+@@ -136,7 +146,7 @@
+ typedef mp_exp_t     mpfr_exp_t;
+ 
+ /* Definition of the standard exponent limits */
+-#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((unsigned long) 1 << 30) - 1))
++#define MPFR_EMAX_DEFAULT ((mpfr_exp_t) (((mpfr_ulong) 1 << 30) - 1))
+ #define MPFR_EMIN_DEFAULT (-(MPFR_EMAX_DEFAULT))
+ 
+ /* Definition of the main structure */
+@@ -725,13 +735,13 @@
+    unexpected results with future compilers and aggressive optimisations.
+    Why not working only with signed types, using INT_MIN and LONG_MIN? */
+ #if __GMP_MP_SIZE_T_INT
+-#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+2))
+-#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+1))
+-#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(unsigned int)0)>>1))+3))
++#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+2))
++#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+1))
++#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(mpfr_uint)0)>>1))+3))
+ #else
+-#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+2))
+-#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+1))
+-#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(unsigned long)0)>>1))+3))
++#define __MPFR_EXP_NAN  ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+2))
++#define __MPFR_EXP_ZERO ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+1))
++#define __MPFR_EXP_INF  ((mpfr_exp_t)((~((~(mpfr_ulong)0)>>1))+3))
+ #endif
+ 
+ /* Define MPFR_USE_EXTENSION to avoid "gcc -pedantic" warnings. */
+@@ -760,9 +770,9 @@
+ #define mpfr_inf_p(_x)      ((_x)->_mpfr_exp == __MPFR_EXP_INF)
+ #define mpfr_zero_p(_x)     ((_x)->_mpfr_exp == __MPFR_EXP_ZERO)
+ #define mpfr_regular_p(_x)  ((_x)->_mpfr_exp >  __MPFR_EXP_INF)
+-#define mpfr_sgn(_x)                                          \
+-  ((_x)->_mpfr_exp < __MPFR_EXP_INF ?                         \
+-   (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (void) 0), 0 : \
++#define mpfr_sgn(_x)                                               \
++  ((_x)->_mpfr_exp < __MPFR_EXP_INF ?                              \
++   (mpfr_nan_p (_x) ? mpfr_set_erangeflag () : (mpfr_void) 0), 0 : \
+    MPFR_SIGN (_x))
+ 
+ /* Prevent them from using as lvalues */
+@@ -805,7 +815,19 @@
+    Moreover casts to unsigned long have been added to avoid warnings in
+    programs that use MPFR and are compiled with -Wconversion; such casts
+    are OK since if X is a constant expression, then (unsigned long) X is
+-   also a constant expression, so that the optimizations still work. */
++   also a constant expression, so that the optimizations still work. The
++   warnings are probably related to the following two bugs:
++     http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4210
++     http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38470 (possibly a variant)
++   and the casts could be removed once these bugs are fixed.
++   Casts shouldn't be used on the generic calls (to the ..._2exp functions),
++   where implicit conversions are performed. Indeed, having at least one
++   implicit conversion in the macro allows the compiler to emit diagnostics
++   when normally expected, for instance in the following call:
++     mpfr_set_ui (x, "foo", MPFR_RNDN);
++   If this is not possible (for future macros), one of the tricks described
++   on http://groups.google.com/group/comp.std.c/msg/e92abd24bf9eaf7b could
++   be used. */
+ #if defined (__GNUC__) && !defined(__ICC) && !defined(__cplusplus)
+ #if (__GNUC__ >= 2)
+ #undef mpfr_cmp_ui
+@@ -813,45 +835,45 @@
+    But warning! mpfr_sgn is specified as a macro in the API, thus the macro
+    mustn't be used if side effects are possible, like here. */
+ #define mpfr_cmp_ui(_f,_u)                                      \
+-  (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ?     \
++  (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ?        \
+    (mpfr_sgn) (_f) :                                            \
+-   mpfr_cmp_ui_2exp ((_f), (unsigned long) (_u), 0))
++   mpfr_cmp_ui_2exp ((_f), (_u), 0))
+ #undef mpfr_cmp_si
+-#define mpfr_cmp_si(_f,_s)                              \
+-  (__builtin_constant_p (_s) && (long) (_s) >= 0 ?      \
+-   mpfr_cmp_ui ((_f), (unsigned long) (long) (_s)) :    \
+-   mpfr_cmp_si_2exp ((_f), (long) (_s), 0))
++#define mpfr_cmp_si(_f,_s)                                      \
++  (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ?         \
++   mpfr_cmp_ui ((_f), (mpfr_ulong) (mpfr_long) (_s)) :          \
++   mpfr_cmp_si_2exp ((_f), (_s), 0))
+ #if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
+ #undef mpfr_set_ui
+ #define mpfr_set_ui(_f,_u,_r)                                   \
+-  (__builtin_constant_p (_u) && (unsigned long) (_u) == 0 ?     \
++  (__builtin_constant_p (_u) && (mpfr_ulong) (_u) == 0 ?        \
+    __extension__ ({                                             \
+        mpfr_ptr _p = (_f);                                      \
+        _p->_mpfr_sign = 1;                                      \
+        _p->_mpfr_exp = __MPFR_EXP_ZERO;                         \
+-       (void) (_r); 0; }) :                                     \
+-   mpfr_set_ui_2exp ((_f), (unsigned long) (_u), 0, (_r)))
++       (mpfr_void) (_r); 0; }) :                                \
++   mpfr_set_ui_2exp ((_f), (_u), 0, (_r)))
+ #endif
+ #undef mpfr_set_si
+ #define mpfr_set_si(_f,_s,_r)                                   \
+-  (__builtin_constant_p (_s) && (long) (_s) >= 0 ?              \
+-   mpfr_set_ui ((_f), (unsigned long) (long) (_s), (_r)) :      \
+-   mpfr_set_si_2exp ((_f), (long) (_s), 0, (_r)))
++  (__builtin_constant_p (_s) && (mpfr_long) (_s) >= 0 ?         \
++   mpfr_set_ui ((_f), (mpfr_ulong) (mpfr_long) (_s), (_r)) :    \
++   mpfr_set_si_2exp ((_f), (_s), 0, (_r)))
+ #endif
+ #endif
+ 
+ /* Macro version of mpfr_stack interface for fast access */
+-#define mpfr_custom_get_size(p) ((size_t)                            \
++#define mpfr_custom_get_size(p) ((mpfr_size_t)                          \
+        (((p)+GMP_NUMB_BITS-1)/GMP_NUMB_BITS*sizeof (mp_limb_t)))
+ #define mpfr_custom_init(m,p) do {} while (0)
+-#define mpfr_custom_get_significand(x) ((void*)((x)->_mpfr_d))
++#define mpfr_custom_get_significand(x) ((mpfr_void*)((x)->_mpfr_d))
+ #define mpfr_custom_get_exp(x) ((x)->_mpfr_exp)
+ #define mpfr_custom_move(x,m) do { ((x)->_mpfr_d = (mp_limb_t*)(m)); } while (0)
+ #define mpfr_custom_init_set(x,k,e,p,m) do {                   \
+   mpfr_ptr _x = (x);                                           \
+   mpfr_exp_t _e;                                               \
+   mpfr_kind_t _t;                                              \
+-  int _s, _k;                                                  \
++  mpfr_int _s, _k;                                             \
+   _k = (k);                                                    \
+   if (_k >= 0)  {                                              \
+     _t = (mpfr_kind_t) _k;                                     \
+@@ -868,11 +890,13 @@
+   _x->_mpfr_exp  = _e;                                         \
+   _x->_mpfr_d    = (mp_limb_t*) (m);                           \
+  } while (0)
+-#define mpfr_custom_get_kind(x)                                              \
+-  ( (x)->_mpfr_exp >  __MPFR_EXP_INF ? (int)MPFR_REGULAR_KIND*MPFR_SIGN (x) \
+-  : (x)->_mpfr_exp == __MPFR_EXP_INF ? (int)MPFR_INF_KIND*MPFR_SIGN (x)     \
+-  : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (int)MPFR_NAN_KIND                   \
+-  : (int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
++#define mpfr_custom_get_kind(x)                                         \
++  ( (x)->_mpfr_exp >  __MPFR_EXP_INF ?                                  \
++    (mpfr_int) MPFR_REGULAR_KIND * MPFR_SIGN (x)                        \
++  : (x)->_mpfr_exp == __MPFR_EXP_INF ?                                  \
++    (mpfr_int) MPFR_INF_KIND * MPFR_SIGN (x)                            \
++  : (x)->_mpfr_exp == __MPFR_EXP_NAN ? (mpfr_int) MPFR_NAN_KIND         \
++  : (mpfr_int) MPFR_ZERO_KIND * MPFR_SIGN (x) )
+ 
+ 
+ #endif /* MPFR_USE_NO_MACRO */
+diff -Naurd mpfr-3.0.0.orig/version.c mpfr-3.0.0/version.c
+--- mpfr-3.0.0.orig/version.c	2010-10-21 21:18:26.000000000 +0000
++++ mpfr-3.0.0/version.c	2010-11-09 15:15:07.000000000 +0000
+@@ -25,5 +25,5 @@
+ const char *
+ mpfr_get_version (void)
+ {
+-  return "3.0.0-p7";
 +  return "3.0.0-p8";
  }