Add libgmp 6.2.0 to third_party

Don't build it yet.  That will come in the next review.

Change-Id: Idf3266558165e5ab45f4a41c98cc8c838c8244d5
diff --git a/third_party/gmp/tests/cxx/Makefile.am b/third_party/gmp/tests/cxx/Makefile.am
new file mode 100644
index 0000000..041bf59
--- /dev/null
+++ b/third_party/gmp/tests/cxx/Makefile.am
@@ -0,0 +1,87 @@
+## Process this file with automake to generate Makefile.in
+
+# Copyright 2001-2004 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library test suite.
+#
+# The GNU MP Library test suite is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the License,
+# or (at your option) any later version.
+#
+# The GNU MP Library test suite is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.
+
+
+# LDADD has an explicit -L of $(top_builddir)/.libs for the benefit of gcc
+# 3.2 on itanium2-hp-hpux11.22.  Without this option, the libgmp.sl.6
+# required by libgmpxx.sl (ie. in its NEEDED records) is not found by the
+# linker.  FIXME: Presumably libtool should do something about this itself.
+# -lm is needed for t-ops2 which compares the results of trunc and mpf_trunc.
+#
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/tests
+AM_LDFLAGS = -no-install
+LDADD = -L$(top_builddir)/.libs \
+  $(top_builddir)/tests/libtests.la \
+  $(top_builddir)/libgmpxx.la \
+  $(top_builddir)/libgmp.la \
+  -lm
+
+if WANT_CXX
+check_PROGRAMS = t-binary t-cast t-cxx11 \
+  t-headers t-iostream t-istream t-locale t-misc t-mix \
+  t-ops t-ops2qf t-ops2f t-ops3 t-ostream t-prec \
+  t-ternary t-unary \
+  t-do-exceptions-work-at-all-with-this-compiler \
+  t-ops2z t-assign t-constr t-rand
+
+TESTS = $(check_PROGRAMS)
+endif
+
+EXTRA_DIST = t-ops2.h
+
+t_assign_SOURCES  = t-assign.cc
+t_binary_SOURCES  = t-binary.cc
+t_cast_SOURCES    = t-cast.cc
+t_constr_SOURCES  = t-constr.cc
+t_cxx11_SOURCES   = t-cxx11.cc
+t_headers_SOURCES = t-headers.cc
+t_iostream_SOURCES= t-iostream.cc
+t_istream_SOURCES = t-istream.cc
+t_locale_SOURCES  = t-locale.cc clocale.c
+t_misc_SOURCES    = t-misc.cc
+t_mix_SOURCES     = t-mix.cc
+t_ops_SOURCES     = t-ops.cc
+t_ops2z_SOURCES   = t-ops2z.cc
+t_ops2qf_SOURCES  = t-ops2qf.cc
+t_ops2f_SOURCES   = t-ops2f.cc
+t_ops3_SOURCES    = t-ops3.cc
+t_ostream_SOURCES = t-ostream.cc
+t_prec_SOURCES    = t-prec.cc
+t_rand_SOURCES    = t-rand.cc
+t_ternary_SOURCES = t-ternary.cc
+t_unary_SOURCES   = t-unary.cc
+t_do_exceptions_work_at_all_with_this_compiler_SOURCES = \
+  t-do-exceptions-work-at-all-with-this-compiler.cc
+
+$(top_builddir)/tests/libtests.la:
+	cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
+
+
+# Libtool (1.5) somehow botches its uninstalled shared library setups on
+# OpenBSD 3.2, making the C++ test programs here fail.  libgmpxx.so ends up
+# with a NEEDED record asking for ./.libs/libgmp.so.N, but the loader can't
+# find that unless it exists in the current directory.
+#
+# FIXME: Clearly libtool ought to handle this itself, in which case the hack
+# here can be removed.
+#
+# Note this fix applies only when running "make check".  The cp here should
+# be done manually if just one program is to be built and run.
+#
+TESTS_ENVIRONMENT = cp $(top_builddir)/.libs/libgmp.so.* .libs 2>/dev/null || true;
diff --git a/third_party/gmp/tests/cxx/Makefile.in b/third_party/gmp/tests/cxx/Makefile.in
new file mode 100644
index 0000000..94ce352
--- /dev/null
+++ b/third_party/gmp/tests/cxx/Makefile.in
@@ -0,0 +1,1445 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright 2001-2004 Free Software Foundation, Inc.
+#
+# This file is part of the GNU MP Library test suite.
+#
+# The GNU MP Library test suite is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the License,
+# or (at your option) any later version.
+#
+# The GNU MP Library test suite is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@WANT_CXX_TRUE@check_PROGRAMS = t-binary$(EXEEXT) t-cast$(EXEEXT) \
+@WANT_CXX_TRUE@	t-cxx11$(EXEEXT) t-headers$(EXEEXT) \
+@WANT_CXX_TRUE@	t-iostream$(EXEEXT) t-istream$(EXEEXT) \
+@WANT_CXX_TRUE@	t-locale$(EXEEXT) t-misc$(EXEEXT) \
+@WANT_CXX_TRUE@	t-mix$(EXEEXT) t-ops$(EXEEXT) t-ops2qf$(EXEEXT) \
+@WANT_CXX_TRUE@	t-ops2f$(EXEEXT) t-ops3$(EXEEXT) \
+@WANT_CXX_TRUE@	t-ostream$(EXEEXT) t-prec$(EXEEXT) \
+@WANT_CXX_TRUE@	t-ternary$(EXEEXT) t-unary$(EXEEXT) \
+@WANT_CXX_TRUE@	t-do-exceptions-work-at-all-with-this-compiler$(EXEEXT) \
+@WANT_CXX_TRUE@	t-ops2z$(EXEEXT) t-assign$(EXEEXT) \
+@WANT_CXX_TRUE@	t-constr$(EXEEXT) t-rand$(EXEEXT)
+subdir = tests/cxx
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am_t_assign_OBJECTS = t-assign.$(OBJEXT)
+t_assign_OBJECTS = $(am_t_assign_OBJECTS)
+t_assign_LDADD = $(LDADD)
+t_assign_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am_t_binary_OBJECTS = t-binary.$(OBJEXT)
+t_binary_OBJECTS = $(am_t_binary_OBJECTS)
+t_binary_LDADD = $(LDADD)
+t_binary_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_cast_OBJECTS = t-cast.$(OBJEXT)
+t_cast_OBJECTS = $(am_t_cast_OBJECTS)
+t_cast_LDADD = $(LDADD)
+t_cast_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_constr_OBJECTS = t-constr.$(OBJEXT)
+t_constr_OBJECTS = $(am_t_constr_OBJECTS)
+t_constr_LDADD = $(LDADD)
+t_constr_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_cxx11_OBJECTS = t-cxx11.$(OBJEXT)
+t_cxx11_OBJECTS = $(am_t_cxx11_OBJECTS)
+t_cxx11_LDADD = $(LDADD)
+t_cxx11_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_do_exceptions_work_at_all_with_this_compiler_OBJECTS =  \
+	t-do-exceptions-work-at-all-with-this-compiler.$(OBJEXT)
+t_do_exceptions_work_at_all_with_this_compiler_OBJECTS =  \
+	$(am_t_do_exceptions_work_at_all_with_this_compiler_OBJECTS)
+t_do_exceptions_work_at_all_with_this_compiler_LDADD = $(LDADD)
+t_do_exceptions_work_at_all_with_this_compiler_DEPENDENCIES =  \
+	$(top_builddir)/tests/libtests.la $(top_builddir)/libgmpxx.la \
+	$(top_builddir)/libgmp.la
+am_t_headers_OBJECTS = t-headers.$(OBJEXT)
+t_headers_OBJECTS = $(am_t_headers_OBJECTS)
+t_headers_LDADD = $(LDADD)
+t_headers_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_iostream_OBJECTS = t-iostream.$(OBJEXT)
+t_iostream_OBJECTS = $(am_t_iostream_OBJECTS)
+t_iostream_LDADD = $(LDADD)
+t_iostream_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_istream_OBJECTS = t-istream.$(OBJEXT)
+t_istream_OBJECTS = $(am_t_istream_OBJECTS)
+t_istream_LDADD = $(LDADD)
+t_istream_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_locale_OBJECTS = t-locale.$(OBJEXT) clocale.$(OBJEXT)
+t_locale_OBJECTS = $(am_t_locale_OBJECTS)
+t_locale_LDADD = $(LDADD)
+t_locale_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_misc_OBJECTS = t-misc.$(OBJEXT)
+t_misc_OBJECTS = $(am_t_misc_OBJECTS)
+t_misc_LDADD = $(LDADD)
+t_misc_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_mix_OBJECTS = t-mix.$(OBJEXT)
+t_mix_OBJECTS = $(am_t_mix_OBJECTS)
+t_mix_LDADD = $(LDADD)
+t_mix_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_ops_OBJECTS = t-ops.$(OBJEXT)
+t_ops_OBJECTS = $(am_t_ops_OBJECTS)
+t_ops_LDADD = $(LDADD)
+t_ops_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_ops2f_OBJECTS = t-ops2f.$(OBJEXT)
+t_ops2f_OBJECTS = $(am_t_ops2f_OBJECTS)
+t_ops2f_LDADD = $(LDADD)
+t_ops2f_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_ops2qf_OBJECTS = t-ops2qf.$(OBJEXT)
+t_ops2qf_OBJECTS = $(am_t_ops2qf_OBJECTS)
+t_ops2qf_LDADD = $(LDADD)
+t_ops2qf_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_ops2z_OBJECTS = t-ops2z.$(OBJEXT)
+t_ops2z_OBJECTS = $(am_t_ops2z_OBJECTS)
+t_ops2z_LDADD = $(LDADD)
+t_ops2z_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_ops3_OBJECTS = t-ops3.$(OBJEXT)
+t_ops3_OBJECTS = $(am_t_ops3_OBJECTS)
+t_ops3_LDADD = $(LDADD)
+t_ops3_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_ostream_OBJECTS = t-ostream.$(OBJEXT)
+t_ostream_OBJECTS = $(am_t_ostream_OBJECTS)
+t_ostream_LDADD = $(LDADD)
+t_ostream_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_prec_OBJECTS = t-prec.$(OBJEXT)
+t_prec_OBJECTS = $(am_t_prec_OBJECTS)
+t_prec_LDADD = $(LDADD)
+t_prec_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_rand_OBJECTS = t-rand.$(OBJEXT)
+t_rand_OBJECTS = $(am_t_rand_OBJECTS)
+t_rand_LDADD = $(LDADD)
+t_rand_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_ternary_OBJECTS = t-ternary.$(OBJEXT)
+t_ternary_OBJECTS = $(am_t_ternary_OBJECTS)
+t_ternary_LDADD = $(LDADD)
+t_ternary_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+am_t_unary_OBJECTS = t-unary.$(OBJEXT)
+t_unary_OBJECTS = $(am_t_unary_OBJECTS)
+t_unary_LDADD = $(LDADD)
+t_unary_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
+	$(top_builddir)/libgmpxx.la $(top_builddir)/libgmp.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp =
+am__depfiles_maybe =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(t_assign_SOURCES) $(t_binary_SOURCES) $(t_cast_SOURCES) \
+	$(t_constr_SOURCES) $(t_cxx11_SOURCES) \
+	$(t_do_exceptions_work_at_all_with_this_compiler_SOURCES) \
+	$(t_headers_SOURCES) $(t_iostream_SOURCES) \
+	$(t_istream_SOURCES) $(t_locale_SOURCES) $(t_misc_SOURCES) \
+	$(t_mix_SOURCES) $(t_ops_SOURCES) $(t_ops2f_SOURCES) \
+	$(t_ops2qf_SOURCES) $(t_ops2z_SOURCES) $(t_ops3_SOURCES) \
+	$(t_ostream_SOURCES) $(t_prec_SOURCES) $(t_rand_SOURCES) \
+	$(t_ternary_SOURCES) $(t_unary_SOURCES)
+DIST_SOURCES = $(t_assign_SOURCES) $(t_binary_SOURCES) \
+	$(t_cast_SOURCES) $(t_constr_SOURCES) $(t_cxx11_SOURCES) \
+	$(t_do_exceptions_work_at_all_with_this_compiler_SOURCES) \
+	$(t_headers_SOURCES) $(t_iostream_SOURCES) \
+	$(t_istream_SOURCES) $(t_locale_SOURCES) $(t_misc_SOURCES) \
+	$(t_mix_SOURCES) $(t_ops_SOURCES) $(t_ops2f_SOURCES) \
+	$(t_ops2qf_SOURCES) $(t_ops2z_SOURCES) $(t_ops3_SOURCES) \
+	$(t_ostream_SOURCES) $(t_prec_SOURCES) $(t_rand_SOURCES) \
+	$(t_ternary_SOURCES) $(t_unary_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI = @ABI@
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+ASMFLAGS = @ASMFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CALLING_CONVENTIONS_OBJS = @CALLING_CONVENTIONS_OBJS@
+CC = @CC@
+CCAS = @CCAS@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPP_FOR_BUILD = @CPP_FOR_BUILD@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFN_LONG_LONG_LIMB = @DEFN_LONG_LONG_LIMB@
+DEFS = @DEFS@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@
+FGREP = @FGREP@
+GMP_LDFLAGS = @GMP_LDFLAGS@
+GMP_LIMB_BITS = @GMP_LIMB_BITS@
+GMP_NAIL_BITS = @GMP_NAIL_BITS@
+GREP = @GREP@
+HAVE_CLOCK_01 = @HAVE_CLOCK_01@
+HAVE_CPUTIME_01 = @HAVE_CPUTIME_01@
+HAVE_GETRUSAGE_01 = @HAVE_GETRUSAGE_01@
+HAVE_GETTIMEOFDAY_01 = @HAVE_GETTIMEOFDAY_01@
+HAVE_HOST_CPU_FAMILY_power = @HAVE_HOST_CPU_FAMILY_power@
+HAVE_HOST_CPU_FAMILY_powerpc = @HAVE_HOST_CPU_FAMILY_powerpc@
+HAVE_SIGACTION_01 = @HAVE_SIGACTION_01@
+HAVE_SIGALTSTACK_01 = @HAVE_SIGALTSTACK_01@
+HAVE_SIGSTACK_01 = @HAVE_SIGSTACK_01@
+HAVE_STACK_T_01 = @HAVE_STACK_T_01@
+HAVE_SYS_RESOURCE_H_01 = @HAVE_SYS_RESOURCE_H_01@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBCURSES = @LIBCURSES@
+LIBGMPXX_LDFLAGS = @LIBGMPXX_LDFLAGS@
+LIBGMP_DLL = @LIBGMP_DLL@
+LIBGMP_LDFLAGS = @LIBGMP_LDFLAGS@
+LIBM = @LIBM@
+LIBM_FOR_BUILD = @LIBM_FOR_BUILD@
+LIBOBJS = @LIBOBJS@
+LIBREADLINE = @LIBREADLINE@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+M4 = @M4@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPEED_CYCLECOUNTER_OBJ = @SPEED_CYCLECOUNTER_OBJ@
+STRIP = @STRIP@
+TAL_OBJECT = @TAL_OBJECT@
+TUNE_LIBS = @TUNE_LIBS@
+TUNE_SQR_OBJ = @TUNE_SQR_OBJ@
+U_FOR_BUILD = @U_FOR_BUILD@
+VERSION = @VERSION@
+WITH_READLINE_01 = @WITH_READLINE_01@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gmp_srclinks = @gmp_srclinks@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+mpn_objects = @mpn_objects@
+mpn_objs_in_libgmp = @mpn_objs_in_libgmp@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# LDADD has an explicit -L of $(top_builddir)/.libs for the benefit of gcc
+# 3.2 on itanium2-hp-hpux11.22.  Without this option, the libgmp.sl.6
+# required by libgmpxx.sl (ie. in its NEEDED records) is not found by the
+# linker.  FIXME: Presumably libtool should do something about this itself.
+# -lm is needed for t-ops2 which compares the results of trunc and mpf_trunc.
+#
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/tests
+AM_LDFLAGS = -no-install
+LDADD = -L$(top_builddir)/.libs \
+  $(top_builddir)/tests/libtests.la \
+  $(top_builddir)/libgmpxx.la \
+  $(top_builddir)/libgmp.la \
+  -lm
+
+@WANT_CXX_TRUE@TESTS = $(check_PROGRAMS)
+EXTRA_DIST = t-ops2.h
+t_assign_SOURCES = t-assign.cc
+t_binary_SOURCES = t-binary.cc
+t_cast_SOURCES = t-cast.cc
+t_constr_SOURCES = t-constr.cc
+t_cxx11_SOURCES = t-cxx11.cc
+t_headers_SOURCES = t-headers.cc
+t_iostream_SOURCES = t-iostream.cc
+t_istream_SOURCES = t-istream.cc
+t_locale_SOURCES = t-locale.cc clocale.c
+t_misc_SOURCES = t-misc.cc
+t_mix_SOURCES = t-mix.cc
+t_ops_SOURCES = t-ops.cc
+t_ops2z_SOURCES = t-ops2z.cc
+t_ops2qf_SOURCES = t-ops2qf.cc
+t_ops2f_SOURCES = t-ops2f.cc
+t_ops3_SOURCES = t-ops3.cc
+t_ostream_SOURCES = t-ostream.cc
+t_prec_SOURCES = t-prec.cc
+t_rand_SOURCES = t-rand.cc
+t_ternary_SOURCES = t-ternary.cc
+t_unary_SOURCES = t-unary.cc
+t_do_exceptions_work_at_all_with_this_compiler_SOURCES = \
+  t-do-exceptions-work-at-all-with-this-compiler.cc
+
+
+# Libtool (1.5) somehow botches its uninstalled shared library setups on
+# OpenBSD 3.2, making the C++ test programs here fail.  libgmpxx.so ends up
+# with a NEEDED record asking for ./.libs/libgmp.so.N, but the loader can't
+# find that unless it exists in the current directory.
+#
+# FIXME: Clearly libtool ought to handle this itself, in which case the hack
+# here can be removed.
+#
+# Note this fix applies only when running "make check".  The cp here should
+# be done manually if just one program is to be built and run.
+#
+TESTS_ENVIRONMENT = cp $(top_builddir)/.libs/libgmp.so.* .libs 2>/dev/null || true;
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps tests/cxx/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu --ignore-deps tests/cxx/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+t-assign$(EXEEXT): $(t_assign_OBJECTS) $(t_assign_DEPENDENCIES) $(EXTRA_t_assign_DEPENDENCIES) 
+	@rm -f t-assign$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_assign_OBJECTS) $(t_assign_LDADD) $(LIBS)
+
+t-binary$(EXEEXT): $(t_binary_OBJECTS) $(t_binary_DEPENDENCIES) $(EXTRA_t_binary_DEPENDENCIES) 
+	@rm -f t-binary$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_binary_OBJECTS) $(t_binary_LDADD) $(LIBS)
+
+t-cast$(EXEEXT): $(t_cast_OBJECTS) $(t_cast_DEPENDENCIES) $(EXTRA_t_cast_DEPENDENCIES) 
+	@rm -f t-cast$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_cast_OBJECTS) $(t_cast_LDADD) $(LIBS)
+
+t-constr$(EXEEXT): $(t_constr_OBJECTS) $(t_constr_DEPENDENCIES) $(EXTRA_t_constr_DEPENDENCIES) 
+	@rm -f t-constr$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_constr_OBJECTS) $(t_constr_LDADD) $(LIBS)
+
+t-cxx11$(EXEEXT): $(t_cxx11_OBJECTS) $(t_cxx11_DEPENDENCIES) $(EXTRA_t_cxx11_DEPENDENCIES) 
+	@rm -f t-cxx11$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_cxx11_OBJECTS) $(t_cxx11_LDADD) $(LIBS)
+
+t-do-exceptions-work-at-all-with-this-compiler$(EXEEXT): $(t_do_exceptions_work_at_all_with_this_compiler_OBJECTS) $(t_do_exceptions_work_at_all_with_this_compiler_DEPENDENCIES) $(EXTRA_t_do_exceptions_work_at_all_with_this_compiler_DEPENDENCIES) 
+	@rm -f t-do-exceptions-work-at-all-with-this-compiler$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_do_exceptions_work_at_all_with_this_compiler_OBJECTS) $(t_do_exceptions_work_at_all_with_this_compiler_LDADD) $(LIBS)
+
+t-headers$(EXEEXT): $(t_headers_OBJECTS) $(t_headers_DEPENDENCIES) $(EXTRA_t_headers_DEPENDENCIES) 
+	@rm -f t-headers$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_headers_OBJECTS) $(t_headers_LDADD) $(LIBS)
+
+t-iostream$(EXEEXT): $(t_iostream_OBJECTS) $(t_iostream_DEPENDENCIES) $(EXTRA_t_iostream_DEPENDENCIES) 
+	@rm -f t-iostream$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_iostream_OBJECTS) $(t_iostream_LDADD) $(LIBS)
+
+t-istream$(EXEEXT): $(t_istream_OBJECTS) $(t_istream_DEPENDENCIES) $(EXTRA_t_istream_DEPENDENCIES) 
+	@rm -f t-istream$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_istream_OBJECTS) $(t_istream_LDADD) $(LIBS)
+
+t-locale$(EXEEXT): $(t_locale_OBJECTS) $(t_locale_DEPENDENCIES) $(EXTRA_t_locale_DEPENDENCIES) 
+	@rm -f t-locale$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_locale_OBJECTS) $(t_locale_LDADD) $(LIBS)
+
+t-misc$(EXEEXT): $(t_misc_OBJECTS) $(t_misc_DEPENDENCIES) $(EXTRA_t_misc_DEPENDENCIES) 
+	@rm -f t-misc$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_misc_OBJECTS) $(t_misc_LDADD) $(LIBS)
+
+t-mix$(EXEEXT): $(t_mix_OBJECTS) $(t_mix_DEPENDENCIES) $(EXTRA_t_mix_DEPENDENCIES) 
+	@rm -f t-mix$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_mix_OBJECTS) $(t_mix_LDADD) $(LIBS)
+
+t-ops$(EXEEXT): $(t_ops_OBJECTS) $(t_ops_DEPENDENCIES) $(EXTRA_t_ops_DEPENDENCIES) 
+	@rm -f t-ops$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_ops_OBJECTS) $(t_ops_LDADD) $(LIBS)
+
+t-ops2f$(EXEEXT): $(t_ops2f_OBJECTS) $(t_ops2f_DEPENDENCIES) $(EXTRA_t_ops2f_DEPENDENCIES) 
+	@rm -f t-ops2f$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_ops2f_OBJECTS) $(t_ops2f_LDADD) $(LIBS)
+
+t-ops2qf$(EXEEXT): $(t_ops2qf_OBJECTS) $(t_ops2qf_DEPENDENCIES) $(EXTRA_t_ops2qf_DEPENDENCIES) 
+	@rm -f t-ops2qf$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_ops2qf_OBJECTS) $(t_ops2qf_LDADD) $(LIBS)
+
+t-ops2z$(EXEEXT): $(t_ops2z_OBJECTS) $(t_ops2z_DEPENDENCIES) $(EXTRA_t_ops2z_DEPENDENCIES) 
+	@rm -f t-ops2z$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_ops2z_OBJECTS) $(t_ops2z_LDADD) $(LIBS)
+
+t-ops3$(EXEEXT): $(t_ops3_OBJECTS) $(t_ops3_DEPENDENCIES) $(EXTRA_t_ops3_DEPENDENCIES) 
+	@rm -f t-ops3$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_ops3_OBJECTS) $(t_ops3_LDADD) $(LIBS)
+
+t-ostream$(EXEEXT): $(t_ostream_OBJECTS) $(t_ostream_DEPENDENCIES) $(EXTRA_t_ostream_DEPENDENCIES) 
+	@rm -f t-ostream$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_ostream_OBJECTS) $(t_ostream_LDADD) $(LIBS)
+
+t-prec$(EXEEXT): $(t_prec_OBJECTS) $(t_prec_DEPENDENCIES) $(EXTRA_t_prec_DEPENDENCIES) 
+	@rm -f t-prec$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_prec_OBJECTS) $(t_prec_LDADD) $(LIBS)
+
+t-rand$(EXEEXT): $(t_rand_OBJECTS) $(t_rand_DEPENDENCIES) $(EXTRA_t_rand_DEPENDENCIES) 
+	@rm -f t-rand$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_rand_OBJECTS) $(t_rand_LDADD) $(LIBS)
+
+t-ternary$(EXEEXT): $(t_ternary_OBJECTS) $(t_ternary_DEPENDENCIES) $(EXTRA_t_ternary_DEPENDENCIES) 
+	@rm -f t-ternary$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_ternary_OBJECTS) $(t_ternary_LDADD) $(LIBS)
+
+t-unary$(EXEEXT): $(t_unary_OBJECTS) $(t_unary_DEPENDENCIES) $(EXTRA_t_unary_DEPENDENCIES) 
+	@rm -f t-unary$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(t_unary_OBJECTS) $(t_unary_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+.c.o:
+	$(AM_V_CC)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+	$(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+	$(AM_V_CC)$(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+	$(AM_V_CXX)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+	$(AM_V_CXX)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+	$(AM_V_CXX)$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	elif test -n "$$redo_logs"; then \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+t-binary.log: t-binary$(EXEEXT)
+	@p='t-binary$(EXEEXT)'; \
+	b='t-binary'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-cast.log: t-cast$(EXEEXT)
+	@p='t-cast$(EXEEXT)'; \
+	b='t-cast'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-cxx11.log: t-cxx11$(EXEEXT)
+	@p='t-cxx11$(EXEEXT)'; \
+	b='t-cxx11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-headers.log: t-headers$(EXEEXT)
+	@p='t-headers$(EXEEXT)'; \
+	b='t-headers'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-iostream.log: t-iostream$(EXEEXT)
+	@p='t-iostream$(EXEEXT)'; \
+	b='t-iostream'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-istream.log: t-istream$(EXEEXT)
+	@p='t-istream$(EXEEXT)'; \
+	b='t-istream'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-locale.log: t-locale$(EXEEXT)
+	@p='t-locale$(EXEEXT)'; \
+	b='t-locale'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-misc.log: t-misc$(EXEEXT)
+	@p='t-misc$(EXEEXT)'; \
+	b='t-misc'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-mix.log: t-mix$(EXEEXT)
+	@p='t-mix$(EXEEXT)'; \
+	b='t-mix'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-ops.log: t-ops$(EXEEXT)
+	@p='t-ops$(EXEEXT)'; \
+	b='t-ops'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-ops2qf.log: t-ops2qf$(EXEEXT)
+	@p='t-ops2qf$(EXEEXT)'; \
+	b='t-ops2qf'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-ops2f.log: t-ops2f$(EXEEXT)
+	@p='t-ops2f$(EXEEXT)'; \
+	b='t-ops2f'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-ops3.log: t-ops3$(EXEEXT)
+	@p='t-ops3$(EXEEXT)'; \
+	b='t-ops3'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-ostream.log: t-ostream$(EXEEXT)
+	@p='t-ostream$(EXEEXT)'; \
+	b='t-ostream'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-prec.log: t-prec$(EXEEXT)
+	@p='t-prec$(EXEEXT)'; \
+	b='t-prec'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-ternary.log: t-ternary$(EXEEXT)
+	@p='t-ternary$(EXEEXT)'; \
+	b='t-ternary'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-unary.log: t-unary$(EXEEXT)
+	@p='t-unary$(EXEEXT)'; \
+	b='t-unary'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-do-exceptions-work-at-all-with-this-compiler.log: t-do-exceptions-work-at-all-with-this-compiler$(EXEEXT)
+	@p='t-do-exceptions-work-at-all-with-this-compiler$(EXEEXT)'; \
+	b='t-do-exceptions-work-at-all-with-this-compiler'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-ops2z.log: t-ops2z$(EXEEXT)
+	@p='t-ops2z$(EXEEXT)'; \
+	b='t-ops2z'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-assign.log: t-assign$(EXEEXT)
+	@p='t-assign$(EXEEXT)'; \
+	b='t-assign'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-constr.log: t-constr$(EXEEXT)
+	@p='t-constr$(EXEEXT)'; \
+	b='t-constr'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+t-rand.log: t-rand$(EXEEXT)
+	@p='t-rand$(EXEEXT)'; \
+	b='t-rand'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@	@p='$<'; \
+@am__EXEEXT_TRUE@	$(am__set_b); \
+@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
+	ctags ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	recheck tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+$(top_builddir)/tests/libtests.la:
+	cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/third_party/gmp/tests/cxx/clocale.c b/third_party/gmp/tests/cxx/clocale.c
new file mode 100644
index 0000000..7f7c36e
--- /dev/null
+++ b/third_party/gmp/tests/cxx/clocale.c
@@ -0,0 +1,66 @@
+/* Manipulable localeconv and nl_langinfo.
+
+Copyright 2001, 2002, 2014 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#if HAVE_NL_TYPES_H
+#include <nl_types.h>  /* for nl_item */
+#endif
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h>  /* for nl_langinfo */
+#endif
+
+#if HAVE_LOCALE_H
+#include <locale.h>    /* for lconv */
+#endif
+
+
+/* Replace the libc localeconv and nl_langinfo with ones we can manipulate.
+
+   This is done in a C file since if it was in a C++ file then we'd have to
+   match the "throw" or lack thereof declared for localeconv in <locale.h>.
+   g++ 3.2 gives an error about mismatched throws under "-pedantic", other
+   C++ compilers may very possibly do so too.  */
+
+extern char point_string[];
+
+#if HAVE_LOCALECONV && ! defined __MINGW32__
+struct lconv *
+localeconv (void)
+#if defined __cplusplus && defined __GLIBC__
+  throw()
+#endif
+{
+  static struct lconv  l;
+  l.decimal_point = point_string;
+  return &l;
+}
+#endif
+
+#if HAVE_NL_LANGINFO
+char *
+nl_langinfo (nl_item n)
+#if defined __cplusplus && defined __GLIBC__
+  throw()
+#endif
+{
+  return point_string;
+}
+#endif
diff --git a/third_party/gmp/tests/cxx/t-assign.cc b/third_party/gmp/tests/cxx/t-assign.cc
new file mode 100644
index 0000000..bd2e41a
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-assign.cc
@@ -0,0 +1,603 @@
+/* Test mp*_class assignment operators.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <iostream>
+#include <string>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using std::string;
+using std::invalid_argument;
+
+
+void
+check_mpz (void)
+{
+  // operator=(const mpz_class &)
+  {
+    mpz_class a(123), b;
+    b = a; ASSERT_ALWAYS(b == 123);
+  }
+
+  // template <class T, class U> operator=(const __gmp_expr<T, U> &)
+  // not tested here, see t-unary.cc, t-binary.cc
+
+  // operator=(signed char)
+  {
+    signed char a = -127;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == -127);
+  }
+
+  // operator=(unsigned char)
+  {
+    unsigned char a = 255;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 255);
+  }
+
+  // either signed or unsigned char, machine dependent
+  {
+    mpz_class a;
+    a = 'A'; ASSERT_ALWAYS(a == 65);
+  }
+  {
+    mpz_class a;
+    a = 'z'; ASSERT_ALWAYS(a == 122);
+  }
+
+  // operator=(signed int)
+  {
+    signed int a = 0;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 0);
+  }
+  {
+    signed int a = -123;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == -123);
+  }
+  {
+    signed int a = 32767;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 32767);
+  }
+
+  // operator=(unsigned int)
+  {
+    unsigned int a = 65535u;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 65535u);
+  }
+
+  // operator=(signed short int)
+  {
+    signed short int a = -12345;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == -12345);
+  }
+
+  // operator=(unsigned short int)
+  {
+    unsigned short int a = 54321u;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 54321u);
+  }
+
+  // operator=(signed long int)
+  {
+    signed long int a = -1234567890L;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == -1234567890L);
+  }
+
+  // operator=(unsigned long int)
+  {
+    unsigned long int a = 3456789012UL;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 3456789012UL);
+  }
+
+  // operator=(float)
+  {
+    float a = 123.0;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 123);
+  }
+
+  // operator=(double)
+  {
+    double a = 0.0;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 0);
+  }
+  {
+    double a = -12.375;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == -12);
+  }
+  {
+    double a = 6.789e+3;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 6789);
+  }
+  {
+    double a = 9.375e-1;
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 0);
+  }
+
+  // operator=(long double)
+  // currently not implemented
+
+  // operator=(const char *)
+  {
+    const char *a = "1234567890";
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // operator=(const std::string &)
+  {
+    string a("1234567890");
+    mpz_class b;
+    b = a; ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // operator=(const char *) with invalid
+  {
+    try {
+      const char *a = "abc";
+      mpz_class b;
+      b = a;
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // operator=(const std::string &) with invalid
+  {
+    try {
+      string a("def");
+      mpz_class b;
+      b = a;
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // swap(mpz_class &)
+  {
+    mpz_class a(123);
+    mpz_class b(456);
+    a.swap(b);
+    a.swap(a);
+    ASSERT_ALWAYS(a == 456);
+    ASSERT_ALWAYS(b == 123);
+  }
+
+  // swap(mpz_class &, mpz_class &)
+  {
+    mpz_class a(123);
+    mpz_class b(456);
+    ::swap(a, b);
+    ::swap(a, a);
+    ASSERT_ALWAYS(a == 456);
+    ASSERT_ALWAYS(b == 123);
+  }
+  {
+    using std::swap;
+    mpz_class a(123);
+    mpz_class b(456);
+    swap(a, b);
+    swap(a, a);
+    ASSERT_ALWAYS(a == 456);
+    ASSERT_ALWAYS(b == 123);
+  }
+}
+
+void
+check_mpq (void)
+{
+  // operator=(const mpq_class &)
+  {
+    mpq_class a(1, 2), b;
+    b = a; ASSERT_ALWAYS(b == 0.5);
+  }
+
+  // template <class T, class U> operator=(const __gmp_expr<T, U> &)
+  // not tested here, see t-unary.cc, t-binary.cc
+
+  // operator=(signed char)
+  {
+    signed char a = -127;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == -127);
+  }
+
+  // operator=(unsigned char)
+  {
+    unsigned char a = 255;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 255);
+  }
+
+  // either signed or unsigned char, machine dependent
+  {
+    mpq_class a;
+    a = 'A'; ASSERT_ALWAYS(a == 65);
+  }
+  {
+    mpq_class a;
+    a = 'z'; ASSERT_ALWAYS(a == 122);
+  }
+
+  // operator=(signed int)
+  {
+    signed int a = 0;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 0);
+  }
+  {
+    signed int a = -123;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == -123);
+  }
+  {
+    signed int a = 32767;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 32767);
+  }
+
+  // operator=(unsigned int)
+  {
+    unsigned int a = 65535u;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 65535u);
+  }
+
+  // operator=(signed short int)
+  {
+    signed short int a = -12345;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == -12345);
+  }
+
+  // operator=(unsigned short int)
+  {
+    unsigned short int a = 54321u;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 54321u);
+  }
+
+  // operator=(signed long int)
+  {
+    signed long int a = -1234567890L;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == -1234567890L);
+  }
+
+  // operator=(unsigned long int)
+  {
+    unsigned long int a = 3456789012UL;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 3456789012UL);
+  }
+
+  // operator=(float)
+  {
+    float a = 123.0;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 123);
+  }
+
+  // operator=(double)
+  {
+    double a = 0.0;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 0);
+  }
+  {
+    double a = -12.375;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == -12.375);
+  }
+  {
+    double a = 6.789e+3;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 6789);
+  }
+  {
+    double a = 9.375e-1;
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 0.9375);
+  }
+
+  // operator=(long double)
+  // currently not implemented
+
+  // operator=(const char *)
+  {
+    const char *a = "1234567890";
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // operator=(const std::string &)
+  {
+    string a("1234567890");
+    mpq_class b;
+    b = a; ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // operator=(const char *) with invalid
+  {
+    try {
+      const char *a = "abc";
+      mpq_class b;
+      b = a;
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // operator=(const std::string &) with invalid
+  {
+    try {
+      string a("def");
+      mpq_class b;
+      b = a;
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // swap(mpq_class &)
+  {
+    mpq_class a(3, 2);
+    mpq_class b(-1, 4);
+    a.swap(b);
+    a.swap(a);
+    ASSERT_ALWAYS(a == -.25);
+    ASSERT_ALWAYS(b == 1.5);
+  }
+
+  // swap(mpq_class &, mpq_class &)
+  {
+    mpq_class a(3, 2);
+    mpq_class b(-1, 4);
+    ::swap(a, b);
+    ::swap(a, a);
+    ASSERT_ALWAYS(a == -.25);
+    ASSERT_ALWAYS(b == 1.5);
+  }
+  {
+    using std::swap;
+    mpq_class a(3, 2);
+    mpq_class b(-1, 4);
+    swap(a, b);
+    swap(a, a);
+    ASSERT_ALWAYS(a == -.25);
+    ASSERT_ALWAYS(b == 1.5);
+  }
+}
+
+void
+check_mpf (void)
+{
+  // operator=(const mpf_class &)
+  {
+    mpf_class a(123), b;
+    b = a; ASSERT_ALWAYS(b == 123);
+  }
+
+  // template <class T, class U> operator=(const __gmp_expr<T, U> &)
+  // not tested here, see t-unary.cc, t-binary.cc
+
+  // operator=(signed char)
+  {
+    signed char a = -127;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == -127);
+  }
+
+  // operator=(unsigned char)
+  {
+    unsigned char a = 255;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 255);
+  }
+
+  // either signed or unsigned char, machine dependent
+  {
+    mpf_class a;
+    a = 'A'; ASSERT_ALWAYS(a == 65);
+  }
+  {
+    mpf_class a;
+    a = 'z'; ASSERT_ALWAYS(a == 122);
+  }
+
+  // operator=(signed int)
+  {
+    signed int a = 0;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 0);
+  }
+  {
+    signed int a = -123;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == -123);
+  }
+  {
+    signed int a = 32767;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 32767);
+  }
+
+  // operator=(unsigned int)
+  {
+    unsigned int a = 65535u;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 65535u);
+  }
+
+  // operator=(signed short int)
+  {
+    signed short int a = -12345;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == -12345);
+  }
+
+  // operator=(unsigned short int)
+  {
+    unsigned short int a = 54321u;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 54321u);
+  }
+
+  // operator=(signed long int)
+  {
+    signed long int a = -1234567890L;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == -1234567890L);
+  }
+
+  // operator=(unsigned long int)
+  {
+    unsigned long int a = 3456789012UL;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 3456789012UL);
+  }
+
+  // operator=(float)
+  {
+    float a = 123.0;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 123);
+  }
+
+  // operator=(double)
+  {
+    double a = 0.0;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 0);
+  }
+  {
+    double a = -12.375;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == -12.375);
+  }
+  {
+    double a = 6.789e+3;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 6789);
+  }
+  {
+    double a = 9.375e-1;
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 0.9375);
+  }
+
+  // operator=(long double)
+  // currently not implemented
+
+  // operator=(const char *)
+  {
+    const char *a = "1234567890";
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // operator=(const std::string &)
+  {
+    string a("1234567890");
+    mpf_class b;
+    b = a; ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // operator=(const char *) with invalid
+  {
+    try {
+      const char *a = "abc";
+      mpf_class b;
+      b = a;
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // operator=(const std::string &) with invalid
+  {
+    try {
+      string a("def");
+      mpf_class b;
+      b = a;
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // swap(mpf_class &)
+  {
+    mpf_class a(123);
+    mpf_class b(456);
+    a.swap(b);
+    a.swap(a);
+    ASSERT_ALWAYS(a == 456);
+    ASSERT_ALWAYS(b == 123);
+  }
+
+  // swap(mpf_class &, mpf_class &)
+  {
+    mpf_class a(123);
+    mpf_class b(456);
+    ::swap(a, b);
+    ::swap(a, a);
+    ASSERT_ALWAYS(a == 456);
+    ASSERT_ALWAYS(b == 123);
+  }
+  {
+    using std::swap;
+    mpf_class a(123);
+    mpf_class b(456);
+    swap(a, b);
+    swap(a, a);
+    ASSERT_ALWAYS(a == 456);
+    ASSERT_ALWAYS(b == 123);
+  }
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpz();
+  check_mpq();
+  check_mpf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-binary.cc b/third_party/gmp/tests/cxx/t-binary.cc
new file mode 100644
index 0000000..697adfa
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-binary.cc
@@ -0,0 +1,465 @@
+/* Test mp*_class binary expressions.
+
+Copyright 2001-2003, 2008, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <iostream>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+void
+check_mpz (void)
+{
+  // template <class T, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
+  {
+    mpz_class a(1), b(2);
+    mpz_class c(a + b); ASSERT_ALWAYS(c == 3);
+  }
+  {
+    mpz_class a(3), b(4);
+    mpz_class c;
+    c = a * b; ASSERT_ALWAYS(c == 12);
+  }
+  {
+    mpz_class a(5), b(3);
+    mpz_class c;
+    c = a % b; ASSERT_ALWAYS(c == 2);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
+  {
+    mpz_class a(1);
+    signed int b = 3;
+    mpz_class c(a - b); ASSERT_ALWAYS(c == -2);
+  }
+  {
+    mpz_class a(-8);
+    unsigned int b = 2;
+    mpz_class c;
+    c = a / b; ASSERT_ALWAYS(c == -4);
+  }
+  {
+    mpz_class a(2);
+    double b = 3.0;
+    mpz_class c(a + b); ASSERT_ALWAYS(c == 5);
+  }
+  {
+    mpz_class a(4);
+    mpz_class b;
+    b = a + 0; ASSERT_ALWAYS(b == 4);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
+  {
+    mpz_class a(3);
+    signed int b = 9;
+    mpz_class c(b / a); ASSERT_ALWAYS(c == 3);
+  }
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
+  // type of result can't be mpz
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
+  // type of result can't be mpz
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
+  {
+    mpz_class a(3), b(4);
+    mpz_class c(a * (-b)); ASSERT_ALWAYS(c == -12);
+    c = c * (-b); ASSERT_ALWAYS(c == 48);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
+  {
+    mpz_class a(3), b(2), c(1);
+    mpz_class d;
+    d = (a % b) + c; ASSERT_ALWAYS(d == 2);
+    d = (a % b) + d; ASSERT_ALWAYS(d == 3);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
+  {
+    mpz_class a(-5);
+    unsigned int b = 2;
+    mpz_class c((-a) << b); ASSERT_ALWAYS(c == 20);
+  }
+  {
+    mpz_class a(5), b(-4);
+    signed int c = 3;
+    mpz_class d;
+    d = (a * b) >> c; ASSERT_ALWAYS(d == -3);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
+  {
+    mpz_class a(2), b(4);
+    double c = 6;
+    mpz_class d(c / (a - b)); ASSERT_ALWAYS(d == -3);
+  }
+  {
+    mpz_class a(3), b(2);
+    double c = 1;
+    mpz_class d;
+    d = c + (a + b); ASSERT_ALWAYS(d == 6);
+  }
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
+  // type of result can't be mpz
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
+  // type of result can't be mpz
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
+  {
+    mpz_class a(3), b(5), c(7);
+    mpz_class d;
+    d = (a - b) * (-c); ASSERT_ALWAYS(d == 14);
+    d = (b - d) * (-a); ASSERT_ALWAYS(d == 27);
+    d = (a - b) * (-d); ASSERT_ALWAYS(d == 54);
+  }
+
+  {
+    mpz_class a(0xcafe), b(0xbeef), c, want;
+    c = a & b; ASSERT_ALWAYS (c == 0x8aee);
+    c = a | b; ASSERT_ALWAYS (c == 0xfeff);
+    c = a ^ b; ASSERT_ALWAYS (c == 0x7411);
+    c = a & 0xbeef; ASSERT_ALWAYS (c == 0x8aee);
+    c = a | 0xbeef; ASSERT_ALWAYS (c == 0xfeff);
+    c = a ^ 0xbeef; ASSERT_ALWAYS (c == 0x7411);
+    c = a & -0xbeef; ASSERT_ALWAYS (c == 0x4010);
+    c = a | -0xbeef; ASSERT_ALWAYS (c == -0x3401);
+    c = a ^ -0xbeef; ASSERT_ALWAYS (c == -0x7411);
+    c = a & 48879.0; ASSERT_ALWAYS (c == 0x8aee);
+    c = a | 48879.0; ASSERT_ALWAYS (c == 0xfeff);
+    c = a ^ 48879.0; ASSERT_ALWAYS (c == 0x7411);
+
+    c = a | 1267650600228229401496703205376.0; // 2^100
+    want = "0x1000000000000000000000cafe";
+    ASSERT_ALWAYS (c == want);
+  }
+
+}
+
+void
+check_mpq (void)
+{
+  // template <class T, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
+  {
+    mpq_class a(1, 2), b(3, 4);
+    mpq_class c(a + b); ASSERT_ALWAYS(c == 1.25);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
+  {
+    mpq_class a(1, 2);
+    signed int b = 3;
+    mpq_class c(a - b); ASSERT_ALWAYS(c == -2.5);
+  }
+  {
+    mpq_class a(1, 2);
+    mpq_class b;
+    b = a + 0; ASSERT_ALWAYS(b == 0.5);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
+  {
+    mpq_class a(2, 3);
+    signed int b = 4;
+    mpq_class c;
+    c = b / a; ASSERT_ALWAYS(c == 6);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
+  {
+    mpq_class a(1, 2);
+    mpz_class b(1);
+    mpq_class c(a + b); ASSERT_ALWAYS(c == 1.5);
+  }
+  {
+    mpq_class a(2, 3);
+    mpz_class b(1);
+    double c = 2.0;
+    mpq_class d;
+    d = a * (b + c); ASSERT_ALWAYS(d == 2);
+    d = d * (b + c); ASSERT_ALWAYS(d == 6);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
+  {
+    mpq_class a(2, 3);
+    mpz_class b(4);
+    mpq_class c(b / a); ASSERT_ALWAYS(c == 6);
+  }
+  {
+    mpq_class a(2, 3);
+    mpz_class b(1), c(4);
+    mpq_class d;
+    d = (b - c) * a; ASSERT_ALWAYS(d == -2);
+    d = (b - c) * d; ASSERT_ALWAYS(d == 6);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
+  {
+    mpq_class a(1, 3), b(3, 4);
+    mpq_class c;
+    c = a * (-b); ASSERT_ALWAYS(c == -0.25);
+    a = a * (-b); ASSERT_ALWAYS(a == -0.25);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
+  {
+    mpq_class a(1, 3), b(2, 3), c(1, 4);
+    mpq_class d((a / b) + c); ASSERT_ALWAYS(d == 0.75);
+    c = (a / b) + c; ASSERT_ALWAYS(c == 0.75);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
+  {
+    mpq_class a(3, 8);
+    unsigned int b = 4;
+    mpq_class c((-a) << b); ASSERT_ALWAYS(c == -6);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
+  {
+    mpq_class a(1, 2), b(1, 4);
+    double c = 6.0;
+    mpq_class d;
+    d = c / (a + b); ASSERT_ALWAYS(d == 8);
+  }
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
+  {
+    mpq_class a(1, 2), b(1, 4);
+    mpz_class c(1);
+    mpq_class d((a + b) - c); ASSERT_ALWAYS(d == -0.25);
+    d = (a + d) - c; ASSERT_ALWAYS(d == -0.75);
+    d = (a + d) - d.get_num(); ASSERT_ALWAYS(d == 2.75);
+    d = (2 * d) * d.get_den(); ASSERT_ALWAYS(d == 22);
+    d = (b * d) / -d.get_num(); ASSERT_ALWAYS(d == -0.25);
+  }
+  {
+    mpq_class a(1, 3), b(3, 2);
+    mpz_class c(2), d(4);
+    mpq_class e;
+    e = (a * b) / (c - d); ASSERT_ALWAYS(e == -0.25);
+    e = (2 * e) / (c - d); ASSERT_ALWAYS(e ==  0.25);
+  }
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
+  {
+    mpq_class a(1, 3), b(3, 4);
+    mpz_class c(-3);
+    mpq_class d(c * (a * b)); ASSERT_ALWAYS(d == -0.75);
+  }
+  {
+    mpq_class a(1, 3), b(3, 5);
+    mpz_class c(6);
+    signed int d = 4;
+    mpq_class e;
+    e = (c % d) / (a * b); ASSERT_ALWAYS(e == 10);
+    e = (e.get_num() % d) / (2 / e); ASSERT_ALWAYS(e == 10);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
+  {
+    mpq_class a(1, 3), b(3, 4), c(2, 5);
+    mpq_class d;
+    d = (a * b) / (-c); ASSERT_ALWAYS(d == -0.625);
+    d = (c * d) / (-b); ASSERT_ALWAYS(3 * d == 1);
+    d = (a * c) / (-d); ASSERT_ALWAYS(5 * d == -2);
+  }
+}
+
+void
+check_mpf (void)
+{
+  // template <class T, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> >
+  {
+    mpf_class a(1), b(2);
+    mpf_class c(a + b); ASSERT_ALWAYS(c == 3);
+  }
+  {
+    mpf_class a(1.5), b(6);
+    mpf_class c;
+    c = a / b; ASSERT_ALWAYS(c == 0.25);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> >
+  {
+    mpf_class a(1);
+    signed int b = -2;
+    mpf_class c(a - b); ASSERT_ALWAYS(c == 3);
+  }
+  {
+    mpf_class a(2);
+    mpf_class b;
+    b = a + 0; ASSERT_ALWAYS(b == 2);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> >
+  {
+    mpf_class a(2);
+    unsigned int b = 3;
+    mpf_class c;
+    c = b / a; ASSERT_ALWAYS(c == 1.5);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> >
+  {
+    mpf_class a(2);
+    mpz_class b(3);
+    mpf_class c(a - b); ASSERT_ALWAYS(c == -1);
+  }
+  {
+    mpf_class a(3);
+    mpz_class b(2), c(1);
+    mpf_class d;
+    d = a * (b + c); ASSERT_ALWAYS(d == 9);
+    a = a * (b + c); ASSERT_ALWAYS(a == 9);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> >
+  {
+    mpf_class a(6);
+    mpq_class b(3, 4);
+    mpf_class c(a * b); ASSERT_ALWAYS(c == 4.5);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> >
+  {
+    mpf_class a(2), b(-3);
+    mpf_class c;
+    c = a * (-b); ASSERT_ALWAYS(c == 6);
+    c = c * (-b); ASSERT_ALWAYS(c == 18);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> >
+  {
+    mpf_class a(3), b(4), c(5);
+    mpf_class d;
+    d = (a / b) - c; ASSERT_ALWAYS(d == -4.25);
+    c = (a / b) - c; ASSERT_ALWAYS(c == -4.25);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
+  {
+    mpf_class a(3);
+    unsigned int b = 2;
+    mpf_class c((-a) >> b); ASSERT_ALWAYS(c == -0.75);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> >
+  {
+    mpf_class a(2), b(3);
+    double c = 5.0;
+    mpf_class d;
+    d = c / (a + b); ASSERT_ALWAYS(d == 1);
+  }
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
+  {
+    mpf_class a(2), b(3);
+    mpz_class c(4);
+    mpf_class d;
+    d = (a + b) * c; ASSERT_ALWAYS(d == 20);
+  }
+  {
+    mpf_class a(2), b(3);
+    mpq_class c(1, 2), d(1, 4);
+    mpf_class e;
+    e = (a * b) / (c + d); ASSERT_ALWAYS(e == 8);
+  }
+
+  // template <class T, class U, class V, class W, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> >
+  {
+    mpf_class a(1), b(2);
+    mpq_class c(3);
+    mpf_class d(c / (a + b)); ASSERT_ALWAYS(d == 1);
+  }
+  {
+    mpf_class a(1);
+    mpz_class b(2);
+    mpq_class c(3, 4);
+    mpf_class d;
+    d = (-c) + (a + b); ASSERT_ALWAYS(d == 2.25);
+  }
+
+  // template <class T, class U, class V, class Op>
+  // __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> >
+  {
+    mpf_class a(1), b(2), c(3);
+    mpf_class d;
+    d = (a + b) * (-c); ASSERT_ALWAYS(d == -9);
+  }
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpz();
+  check_mpq();
+  check_mpf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-cast.cc b/third_party/gmp/tests/cxx/t-cast.cc
new file mode 100644
index 0000000..983b3b8
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-cast.cc
@@ -0,0 +1,56 @@
+/* Test g++ -Wold-style-cast cleanliness.
+
+Copyright 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "gmpxx.h"
+
+
+/* This code doesn't do anything when run, it just expands various C macros
+   to see that they don't trigger compile-time warnings from g++
+   -Wold-style-cast.  This option isn't used in a normal build, it has to be
+   added manually to make this test worthwhile.  */
+
+void
+check_macros (void)
+{
+  mpz_t          z;
+  long           l = 123;
+  unsigned long  u = 456;
+  int            i;
+  mp_limb_t      limb;
+
+  mpz_init_set_ui (z, 0L);
+  i = mpz_odd_p (z);
+  i = mpz_even_p (z);
+  i = mpz_cmp_si (z, l);
+  i = mpz_cmp_ui (z, u);
+  mpz_clear (z);
+
+  limb = GMP_NUMB_MASK;
+  limb = GMP_NUMB_MAX;
+  limb = GMP_NAIL_MASK;
+
+  mpn_divmod (&limb, &limb, 1, &limb, 1);
+  mpn_divexact_by3 (&limb, &limb, 1);
+}
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-constr.cc b/third_party/gmp/tests/cxx/t-constr.cc
new file mode 100644
index 0000000..0b2ac97
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-constr.cc
@@ -0,0 +1,755 @@
+/* Test mp*_class constructors.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <iostream>
+#include <string>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+void
+check_mpz (void)
+{
+  // mpz_class()
+  {
+    mpz_class a; ASSERT_ALWAYS(a == 0);
+  }
+
+  // mpz_class(const mpz_class &)
+  // see below
+
+  // template <class T, class U> mpz_class(const __gmp_expr<T, U> &)
+  // not tested here, see t-unary.cc, t-binary.cc
+
+  // mpz_class(signed char)
+  {
+    signed char a = -127;
+    mpz_class b(a); ASSERT_ALWAYS(b == -127);
+  }
+
+  // mpz_class(unsigned char)
+  {
+    unsigned char a = 255;
+    mpz_class b(a); ASSERT_ALWAYS(b == 255);
+  }
+
+  // either signed or unsigned char, machine dependent
+  {
+    mpz_class a('A'); ASSERT_ALWAYS(a == 65);
+  }
+  {
+    mpz_class a('z'); ASSERT_ALWAYS(a == 122);
+  }
+
+  // mpz_class(signed int)
+  {
+    signed int a = 0;
+    mpz_class b(a); ASSERT_ALWAYS(b == 0);
+  }
+  {
+    signed int a = -123;
+    mpz_class b(a); ASSERT_ALWAYS(b == -123);
+  }
+  {
+    signed int a = 4567;
+    mpz_class b(a); ASSERT_ALWAYS(b == 4567);
+  }
+
+  // mpz_class(unsigned int)
+  {
+    unsigned int a = 890;
+    mpz_class b(a); ASSERT_ALWAYS(b == 890);
+  }
+
+  // mpz_class(signed short int)
+  {
+    signed short int a = -12345;
+    mpz_class b(a); ASSERT_ALWAYS(b == -12345);
+  }
+
+  // mpz_class(unsigned short int)
+  {
+    unsigned short int a = 54321u;
+    mpz_class b(a); ASSERT_ALWAYS(b == 54321u);
+  }
+
+  // mpz_class(signed long int)
+  {
+    signed long int a = -1234567890L;
+    mpz_class b(a); ASSERT_ALWAYS(b == -1234567890L);
+  }
+
+  // mpz_class(unsigned long int)
+  {
+    unsigned long int a = 1UL << 30;
+    mpz_class b(a); ASSERT_ALWAYS(b == 1073741824L);
+  }
+
+  // mpz_class(float)
+  {
+    float a = 123.45;
+    mpz_class b(a); ASSERT_ALWAYS(b == 123);
+  }
+
+  // mpz_class(double)
+  {
+    double a = 3.141592653589793238;
+    mpz_class b(a); ASSERT_ALWAYS(b == 3);
+  }
+
+  // mpz_class(long double)
+  // currently not implemented
+
+  // mpz_class(const char *)
+  {
+    const char *a = "1234567890";
+    mpz_class b(a); ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // mpz_class(const char *, int)
+  {
+    const char *a = "FFFF";
+    int base = 16;
+    mpz_class b(a, base); ASSERT_ALWAYS(b == 65535u);
+  }
+
+  // mpz_class(const std::string &)
+  {
+    string a("1234567890");
+    mpz_class b(a); ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // mpz_class(const std::string &, int)
+  {
+    string a("7777");
+    int base = 8;
+    mpz_class b(a, base); ASSERT_ALWAYS(b == 4095);
+  }
+
+  // mpz_class(const char *) with invalid
+  {
+    try {
+      const char *a = "ABC";
+      mpz_class b(a);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpz_class(const char *, int) with invalid
+  {
+    try {
+      const char *a = "GHI";
+      int base = 16;
+      mpz_class b(a, base);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpz_class(const std::string &) with invalid
+  {
+    try {
+      string a("abc");
+      mpz_class b(a);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpz_class(const std::string &, int) with invalid
+  {
+    try {
+      string a("ZZZ");
+      int base = 8;
+      mpz_class b(a, base);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpz_class(mpz_srcptr)
+  {
+    mpz_t a;
+    mpz_init_set_ui(a, 100);
+    mpz_class b(a); ASSERT_ALWAYS(b == 100);
+    mpz_clear(a);
+  }
+
+  // mpz_class(const mpz_class &)
+  {
+    mpz_class a(12345); // tested above, assume it works
+    mpz_class b(a); ASSERT_ALWAYS(b == 12345);
+  }
+
+  // no constructor for bool, but it gets casted to int
+  {
+    bool a = true;
+    mpz_class b(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    bool a = false;
+    mpz_class b(a); ASSERT_ALWAYS(b == 0);
+  }
+}
+
+void
+check_mpq (void)
+{
+  // mpq_class()
+  {
+    mpq_class a; ASSERT_ALWAYS(a == 0);
+  }
+
+  // mpq_class(const mpq_class &)
+  // see below
+
+  // template <class T, class U> mpq_class(const __gmp_expr<T, U> &)
+  // not tested here, see t-unary.cc, t-binary.cc
+
+  // mpq_class(signed char)
+  {
+    signed char a = -127;
+    mpq_class b(a); ASSERT_ALWAYS(b == -127);
+  }
+
+  // mpq_class(unsigned char)
+  {
+    unsigned char a = 255;
+    mpq_class b(a); ASSERT_ALWAYS(b == 255);
+  }
+
+  // either signed or unsigned char, machine dependent
+  {
+    mpq_class a('A'); ASSERT_ALWAYS(a == 65);
+  }
+  {
+    mpq_class a('z'); ASSERT_ALWAYS(a == 122);
+  }
+
+  // mpq_class(signed int)
+  {
+    signed int a = 0;
+    mpq_class b(a); ASSERT_ALWAYS(b == 0);
+  }
+  {
+    signed int a = -123;
+    mpq_class b(a); ASSERT_ALWAYS(b == -123);
+  }
+  {
+    signed int a = 4567;
+    mpq_class b(a); ASSERT_ALWAYS(b == 4567);
+  }
+
+  // mpq_class(unsigned int)
+  {
+    unsigned int a = 890;
+    mpq_class b(a); ASSERT_ALWAYS(b == 890);
+  }
+
+  // mpq_class(signed short int)
+  {
+    signed short int a = -12345;
+    mpq_class b(a); ASSERT_ALWAYS(b == -12345);
+  }
+
+  // mpq_class(unsigned short int)
+  {
+    unsigned short int a = 54321u;
+    mpq_class b(a); ASSERT_ALWAYS(b == 54321u);
+  }
+
+  // mpq_class(signed long int)
+  {
+    signed long int a = -1234567890L;
+    mpq_class b(a); ASSERT_ALWAYS(b == -1234567890L);
+  }
+
+  // mpq_class(unsigned long int)
+  {
+    unsigned long int a = 1UL << 30;
+    mpq_class b(a); ASSERT_ALWAYS(b == 1073741824L);
+  }
+
+  // mpq_class(float)
+  {
+    float a = 0.625;
+    mpq_class b(a); ASSERT_ALWAYS(b == 0.625);
+  }
+
+  // mpq_class(double)
+  {
+    double a = 1.25;
+    mpq_class b(a); ASSERT_ALWAYS(b == 1.25);
+  }
+
+  // mpq_class(long double)
+  // currently not implemented
+
+  // mpq_class(const char *)
+  {
+    const char *a = "1234567890";
+    mpq_class b(a); ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // mpq_class(const char *, int)
+  {
+    const char *a = "FFFF";
+    int base = 16;
+    mpq_class b(a, base); ASSERT_ALWAYS(b == 65535u);
+    mpq_class c(0, 1); ASSERT_ALWAYS(c == 0);
+  }
+
+  // mpq_class(const std::string &)
+  {
+    string a("1234567890");
+    mpq_class b(a); ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // mpq_class(const std::string &, int)
+  {
+    string a("7777");
+    int base = 8;
+    mpq_class b(a, base); ASSERT_ALWAYS(b == 4095);
+  }
+
+  // mpq_class(const char *) with invalid
+  {
+    try {
+      const char *a = "abc";
+      mpq_class b(a);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpq_class(const char *, int) with invalid
+  {
+    try {
+      const char *a = "ZZZ";
+      int base = 16;
+      mpq_class b (a, base);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpq_class(const std::string &) with invalid
+  {
+    try {
+      string a("abc");
+      mpq_class b(a);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpq_class(const std::string &, int) with invalid
+  {
+    try {
+      string a("ZZZ");
+      int base = 8;
+      mpq_class b (a, base);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpq_class(mpq_srcptr)
+  {
+    mpq_t a;
+    mpq_init(a);
+    mpq_set_ui(a, 100, 1);
+    mpq_class b(a); ASSERT_ALWAYS(b == 100);
+    mpq_clear(a);
+  }
+
+  // mpq_class(const mpz_class &, const mpz_class &)
+  {
+    mpz_class a(123), b(4); // tested above, assume it works
+    mpq_class c(a, b); ASSERT_ALWAYS(c == 30.75);
+  }
+  {
+    mpz_class a(-1), b(2);  // tested above, assume it works
+    mpq_class c(a, b); ASSERT_ALWAYS(c == -0.5);
+  }
+  {
+    mpz_class a(5), b(4); // tested above, assume it works
+    mpq_class c(a, b); ASSERT_ALWAYS(c == 1.25);
+  }
+
+  // mpq_class(const mpz_class &)
+  {
+    mpq_class a(12345); // tested above, assume it works
+    mpq_class b(a); ASSERT_ALWAYS(b == 12345);
+  }
+
+  // no constructor for bool, but it gets casted to int
+  {
+    bool a = true;
+    mpq_class b(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    bool a = false;
+    mpq_class b(a); ASSERT_ALWAYS(b == 0);
+  }
+}
+
+void
+check_mpf (void)
+{
+  // mpf_class()
+  {
+    mpf_class a; ASSERT_ALWAYS(a == 0);
+  }
+
+  // mpf_class(const mpf_class &)
+  // mpf_class(const mpf_class &, unsigned long int)
+  // see below
+
+  // template <class T, class U> mpf_class(const __gmp_expr<T, U> &)
+  // template <class T, class U> mpf_class(const __gmp_expr<T, U> &,
+  //                                       unsigned long int)
+  // not tested here, see t-unary.cc, t-binary.cc
+
+  // mpf_class(signed char)
+  {
+    signed char a = -127;
+    mpf_class b(a); ASSERT_ALWAYS(b == -127);
+  }
+
+  // mpf_class(signed char, unsigned long int)
+  {
+    signed char a = -1;
+    int prec = 64;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == -1);
+  }
+
+  // mpf_class(unsigned char)
+  {
+    unsigned char a = 255;
+    mpf_class b(a); ASSERT_ALWAYS(b == 255);
+  }
+
+  // mpf_class(unsigned char, unsigned long int)
+  {
+    unsigned char a = 128;
+    int prec = 128;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 128);
+  }
+
+  // either signed or unsigned char, machine dependent
+  {
+    mpf_class a('A'); ASSERT_ALWAYS(a == 65);
+  }
+  {
+    int prec = 256;
+    mpf_class a('z', prec); ASSERT_ALWAYS(a == 122);
+  }
+
+  // mpf_class(signed int)
+  {
+    signed int a = 0;
+    mpf_class b(a); ASSERT_ALWAYS(b == 0);
+  }
+  {
+    signed int a = -123;
+    mpf_class b(a); ASSERT_ALWAYS(b == -123);
+  }
+  {
+    signed int a = 4567;
+    mpf_class b(a); ASSERT_ALWAYS(b == 4567);
+  }
+
+  // mpf_class(signed int, unsigned long int)
+  {
+    signed int a = -123;
+    int prec = 64;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == -123);
+  }
+
+  // mpf_class(unsigned int)
+  {
+    unsigned int a = 890;
+    mpf_class b(a); ASSERT_ALWAYS(b == 890);
+  }
+
+  // mpf_class(unsigned int, unsigned long int)
+  {
+    unsigned int a = 890;
+    int prec = 128;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 890);
+  }
+
+  // mpf_class(signed short int)
+  {
+    signed short int a = -12345;
+    mpf_class b(a); ASSERT_ALWAYS(b == -12345);
+  }
+
+  // mpf_class(signed short int, unsigned long int)
+  {
+    signed short int a = 6789;
+    int prec = 256;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 6789);
+  }
+
+  // mpf_class(unsigned short int)
+  {
+    unsigned short int a = 54321u;
+    mpf_class b(a); ASSERT_ALWAYS(b == 54321u);
+  }
+
+  // mpf_class(unsigned short int, unsigned long int)
+  {
+    unsigned short int a = 54321u;
+    int prec = 64;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 54321u);
+  }
+
+  // mpf_class(signed long int)
+  {
+    signed long int a = -1234567890L;
+    mpf_class b(a); ASSERT_ALWAYS(b == -1234567890L);
+  }
+
+  // mpf_class(signed long int, unsigned long int)
+  {
+    signed long int a = -1234567890L;
+    int prec = 128;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == -1234567890L);
+  }
+
+  // mpf_class(unsigned long int)
+  {
+    unsigned long int a = 3456789012UL;
+    mpf_class b(a); ASSERT_ALWAYS(b == 3456789012UL);
+  }
+
+  // mpf_class(unsigned long int, unsigned long int)
+  {
+    unsigned long int a = 3456789012UL;
+    int prec = 256;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 3456789012UL);
+  }
+
+  // mpf_class(float)
+  {
+    float a = 1234.5;
+    mpf_class b(a); ASSERT_ALWAYS(b == 1234.5);
+  }
+
+  // mpf_class(float, unsigned long int)
+  {
+    float a = 1234.5;
+    int prec = 64;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 1234.5);
+  }
+
+  // mpf_class(double)
+  {
+    double a = 12345.0;
+    mpf_class b(a); ASSERT_ALWAYS(b == 12345);
+  }
+  {
+    double a = 1.2345e+4;
+    mpf_class b(a); ASSERT_ALWAYS(b == 12345);
+  }
+  {
+    double a = 312.5e-2;
+    mpf_class b(a); ASSERT_ALWAYS(b == 3.125);
+  }
+
+  // mpf_class(double, unsigned long int)
+  {
+    double a = 5.4321e+4;
+    int prec = 128;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 54321L);
+  }
+
+  // mpf_class(long double)
+  // mpf_class(long double, unsigned long int)
+  // currently not implemented
+
+  // mpf_class(const char *)
+  {
+    const char *a = "1234567890";
+    mpf_class b(a); ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // mpf_class(const char *, unsigned long int, int = 0)
+  {
+    const char *a = "1234567890";
+    int prec = 256;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 1234567890L);
+  }
+  {
+    const char *a = "777777";
+    int prec = 64, base = 8;
+    mpf_class b(a, prec, base); ASSERT_ALWAYS(b == 262143L);
+  }
+
+  // mpf_class(const std::string &)
+  {
+    string a("1234567890");
+    mpf_class b(a); ASSERT_ALWAYS(b == 1234567890L);
+  }
+
+  // mpf_class(const std::string &, unsigned long int, int = 0)
+  {
+    string a("1234567890");
+    int prec = 128;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 1234567890L);
+  }
+  {
+    string a("FFFF");
+    int prec = 256, base = 16;
+    mpf_class b(a, prec, base); ASSERT_ALWAYS(b == 65535u);
+  }
+
+  // mpf_class(const char *) with invalid
+  {
+    try {
+      const char *a = "abc";
+      mpf_class b(a);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpf_class(const char *, unsigned long int, int = 0) with invalid
+  {
+    try {
+      const char *a = "def";
+      int prec = 256;
+      mpf_class b(a, prec); ASSERT_ALWAYS(b == 1234567890L);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+  {
+    try {
+      const char *a = "ghi";
+      int prec = 64, base = 8;
+      mpf_class b(a, prec, base); ASSERT_ALWAYS(b == 262143L);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpf_class(const std::string &) with invalid
+  {
+    try {
+      string a("abc");
+      mpf_class b(a); ASSERT_ALWAYS(b == 1234567890L);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpf_class(const std::string &, unsigned long int, int = 0) with invalid
+  {
+    try {
+      string a("def");
+      int prec = 128;
+      mpf_class b(a, prec); ASSERT_ALWAYS(b == 1234567890L);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+  {
+    try {
+      string a("ghi");
+      int prec = 256, base = 16;
+      mpf_class b(a, prec, base); ASSERT_ALWAYS(b == 65535u);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (invalid_argument) {
+    }
+  }
+
+  // mpf_class(mpf_srcptr)
+  {
+    mpf_t a;
+    mpf_init_set_ui(a, 100);
+    mpf_class b(a); ASSERT_ALWAYS(b == 100);
+    mpf_clear(a);
+  }
+
+  // mpf_class(mpf_srcptr, unsigned long int)
+  {
+    mpf_t a;
+    int prec = 64;
+    mpf_init_set_ui(a, 100);
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 100);
+    mpf_clear(a);
+  }
+
+  // mpf_class(const mpf_class &)
+  {
+    mpf_class a(12345); // tested above, assume it works
+    mpf_class b(a); ASSERT_ALWAYS(b == 12345);
+  }
+
+  // mpf_class(const mpf_class &, unsigned long int)
+  {
+    mpf_class a(12345); // tested above, assume it works
+    int prec = 64;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 12345);
+  }
+
+  // no constructors for bool, but it gets casted to int
+  {
+    bool a = true;
+    mpf_class b(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    bool a = false;
+    mpf_class b(a); ASSERT_ALWAYS(b == 0);
+  }
+  {
+    bool a = true;
+    int prec = 128;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    bool a = false;
+    int prec = 256;
+    mpf_class b(a, prec); ASSERT_ALWAYS(b == 0);
+  }
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpz();
+  check_mpq();
+  check_mpf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-cxx11.cc b/third_party/gmp/tests/cxx/t-cxx11.cc
new file mode 100644
index 0000000..8d6fccb
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-cxx11.cc
@@ -0,0 +1,232 @@
+/* Test C++11 features
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#if __GMPXX_USE_CXX11
+
+#include <utility>
+#include <type_traits>
+
+void check_noexcept ()
+{
+  mpz_class z1, z2;
+  mpq_class q1, q2;
+  mpf_class f1, f2;
+  static_assert(noexcept(z1 = std::move(z2)), "sorry");
+  static_assert(noexcept(q1 = std::move(q2)), "sorry");
+  static_assert(noexcept(f1 = std::move(f2)), "sorry");
+  static_assert(noexcept(q1 = std::move(z1)), "sorry");
+
+  // Only mpz has lazy allocation for now
+  static_assert(std::is_nothrow_default_constructible<mpz_class>::value, "sorry");
+  static_assert(std::is_nothrow_move_constructible<mpz_class>::value, "sorry");
+  static_assert(!std::is_nothrow_default_constructible<mpq_class>::value, "sorry");
+  static_assert(!std::is_nothrow_move_constructible<mpq_class>::value, "sorry");
+  static_assert(!std::is_nothrow_default_constructible<mpf_class>::value, "sorry");
+  static_assert(!std::is_nothrow_move_constructible<mpf_class>::value, "sorry");
+}
+
+void check_common_type ()
+{
+#define CHECK_COMMON_TYPE1(T, Res) \
+  static_assert(std::is_same<std::common_type<T>::type, Res>::value, "sorry")
+#define CHECK_COMMON_TYPE(T, U, Res) \
+  static_assert(std::is_same<std::common_type<T, U>::type, Res>::value, "sorry")
+#define CHECK_COMMON_TYPE_BUILTIN1(T, Res) \
+  CHECK_COMMON_TYPE(  signed char , T, Res); \
+  CHECK_COMMON_TYPE(unsigned char , T, Res); \
+  CHECK_COMMON_TYPE(  signed short, T, Res); \
+  CHECK_COMMON_TYPE(unsigned short, T, Res); \
+  CHECK_COMMON_TYPE(  signed int  , T, Res); \
+  CHECK_COMMON_TYPE(unsigned int  , T, Res); \
+  CHECK_COMMON_TYPE(  signed long , T, Res); \
+  CHECK_COMMON_TYPE(unsigned long , T, Res); \
+  CHECK_COMMON_TYPE(float , T, Res); \
+  CHECK_COMMON_TYPE(double, T, Res)
+#define CHECK_COMMON_TYPE_BUILTIN2(T, Res) \
+  CHECK_COMMON_TYPE(T,   signed char , Res); \
+  CHECK_COMMON_TYPE(T, unsigned char , Res); \
+  CHECK_COMMON_TYPE(T,   signed short, Res); \
+  CHECK_COMMON_TYPE(T, unsigned short, Res); \
+  CHECK_COMMON_TYPE(T,   signed int  , Res); \
+  CHECK_COMMON_TYPE(T, unsigned int  , Res); \
+  CHECK_COMMON_TYPE(T,   signed long , Res); \
+  CHECK_COMMON_TYPE(T, unsigned long , Res); \
+  CHECK_COMMON_TYPE(T, float , Res); \
+  CHECK_COMMON_TYPE(T, double, Res)
+#define CHECK_COMMON_TYPE_BUILTIN(T, Res) \
+  CHECK_COMMON_TYPE_BUILTIN1(T, Res); \
+  CHECK_COMMON_TYPE_BUILTIN2(T, Res)
+  /* These would just work with implicit conversions */
+  CHECK_COMMON_TYPE (mpz_class, mpq_class, mpq_class);
+  CHECK_COMMON_TYPE (mpz_class, mpf_class, mpf_class);
+  CHECK_COMMON_TYPE (mpf_class, mpq_class, mpf_class);
+
+  CHECK_COMMON_TYPE_BUILTIN (mpz_class, mpz_class);
+  CHECK_COMMON_TYPE_BUILTIN (mpq_class, mpq_class);
+  CHECK_COMMON_TYPE_BUILTIN (mpf_class, mpf_class);
+
+  mpz_class z; mpq_class q; mpf_class f;
+
+  CHECK_COMMON_TYPE (decltype(-z), mpz_class, mpz_class);
+  CHECK_COMMON_TYPE (decltype(-q), mpq_class, mpq_class);
+  CHECK_COMMON_TYPE (decltype(-f), mpf_class, mpf_class);
+
+  CHECK_COMMON_TYPE (decltype(-z), mpq_class, mpq_class);
+  CHECK_COMMON_TYPE (decltype(-z), mpf_class, mpf_class);
+  CHECK_COMMON_TYPE (decltype(-q), mpf_class, mpf_class);
+
+  /* These require a common_type specialization */
+  CHECK_COMMON_TYPE (decltype(-z), decltype(z+z), mpz_class);
+  CHECK_COMMON_TYPE (decltype(-q), decltype(q+q), mpq_class);
+  CHECK_COMMON_TYPE (decltype(-f), decltype(f+f), mpf_class);
+
+  CHECK_COMMON_TYPE (decltype(-q), mpz_class, mpq_class);
+  CHECK_COMMON_TYPE (decltype(-f), mpz_class, mpf_class);
+  CHECK_COMMON_TYPE (decltype(-f), mpq_class, mpf_class);
+
+  CHECK_COMMON_TYPE (decltype(-z), decltype(-q), mpq_class);
+  CHECK_COMMON_TYPE (decltype(-z), decltype(-f), mpf_class);
+  CHECK_COMMON_TYPE (decltype(-q), decltype(-f), mpf_class);
+
+  /* common_type now decays */
+  CHECK_COMMON_TYPE (decltype(-z), decltype(-z), mpz_class);
+  CHECK_COMMON_TYPE (decltype(-q), decltype(-q), mpq_class);
+  CHECK_COMMON_TYPE (decltype(-f), decltype(-f), mpf_class);
+  CHECK_COMMON_TYPE1 (decltype(-z), mpz_class);
+  CHECK_COMMON_TYPE1 (decltype(-q), mpq_class);
+  CHECK_COMMON_TYPE1 (decltype(-f), mpf_class);
+
+  /* Painful */
+  CHECK_COMMON_TYPE_BUILTIN (decltype(-z), mpz_class);
+  CHECK_COMMON_TYPE_BUILTIN (decltype(-q), mpq_class);
+  CHECK_COMMON_TYPE_BUILTIN (decltype(-f), mpf_class);
+}
+
+template<class T, class U = T>
+void check_move_init ()
+{
+  {
+    // Delete moved-from x1
+    T x1 = 3;
+    U x2 = std::move(x1);
+    ASSERT_ALWAYS (x2 == 3);
+  }
+  {
+    // Assign to moved-from x1
+    T x1 = 2;
+    U x2 = std::move(x1);
+    x1 = -7;
+    ASSERT_ALWAYS (x1 == -7);
+    ASSERT_ALWAYS (x2 == 2);
+  }
+}
+
+template<class T, class U = T>
+void check_move_assign ()
+{
+  {
+    // Delete moved-from x1
+    T x1 = 3; U x2;
+    x2 = std::move(x1);
+    ASSERT_ALWAYS (x2 == 3);
+  }
+  {
+    // Assign to moved-from x1
+    T x1 = 2; U x2;
+    x2 = std::move(x1);
+    x1 = -7;
+    ASSERT_ALWAYS (x1 == -7);
+    ASSERT_ALWAYS (x2 == 2);
+  }
+  {
+    // Self move-assign (not necessary, but it happens to work...)
+    T x = 4;
+    x = std::move(x);
+    ASSERT_ALWAYS (x == 4);
+  }
+}
+
+void check_user_defined_literal ()
+{
+  ASSERT_ALWAYS (123_mpz % 5 == 3);
+  ASSERT_ALWAYS (-11_mpq / 22 == -.5);
+  ASSERT_ALWAYS (112.5e-1_mpf * 4 == 45);
+  {
+    mpz_class ref ( "123456789abcdef0123456789abcdef0123", 16);
+    ASSERT_ALWAYS (0x123456789abcdef0123456789abcdef0123_mpz == ref);
+  }
+}
+
+// Check for explicit conversion to bool
+void implicit_bool(bool);
+int implicit_bool(...);
+
+void check_bool_conversion ()
+{
+  const mpz_class zn = -2;
+  const mpq_class qn = -2;
+  const mpf_class fn = -2;
+  const mpz_class z0 =  0;
+  const mpq_class q0 =  0;
+  const mpf_class f0 =  0;
+  const mpz_class zp = +2;
+  const mpq_class qp = +2;
+  const mpf_class fp = +2;
+  if (zn && qn && fn && zp && qp && fp && !z0 && !q0 && !f0)
+    {
+      if (z0 || q0 || f0) ASSERT_ALWAYS(false);
+    }
+  else ASSERT_ALWAYS(false);
+  decltype(implicit_bool(zn)) zi = 1;
+  decltype(implicit_bool(qn)) qi = 1;
+  decltype(implicit_bool(fn)) fi = 1;
+  (void)(zi+qi+fi);
+}
+
+int
+main (void)
+{
+  tests_start();
+
+  check_noexcept();
+  check_common_type();
+  check_move_init<mpz_class>();
+  check_move_init<mpq_class>();
+  check_move_init<mpf_class>();
+  check_move_assign<mpz_class>();
+  check_move_assign<mpq_class>();
+  check_move_assign<mpf_class>();
+  check_move_init<mpz_class,mpq_class>();
+  check_move_assign<mpz_class,mpq_class>();
+  check_user_defined_literal();
+  check_bool_conversion();
+
+  tests_end();
+  return 0;
+}
+
+#else
+int main () { return 0; }
+#endif
diff --git a/third_party/gmp/tests/cxx/t-do-exceptions-work-at-all-with-this-compiler.cc b/third_party/gmp/tests/cxx/t-do-exceptions-work-at-all-with-this-compiler.cc
new file mode 100644
index 0000000..341a818
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-do-exceptions-work-at-all-with-this-compiler.cc
@@ -0,0 +1,38 @@
+/* Test if the compiler has working try / throw / catch.
+
+Copyright 2013 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include <stdexcept>
+
+inline void
+throw_expr ()
+{
+  throw std::invalid_argument ("Test");
+}
+
+using namespace std;
+
+int
+main ()
+{
+  try
+  {
+    throw_expr();
+  }
+  catch (invalid_argument) { }
+}
diff --git a/third_party/gmp/tests/cxx/t-headers.cc b/third_party/gmp/tests/cxx/t-headers.cc
new file mode 100644
index 0000000..35f7a25
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-headers.cc
@@ -0,0 +1,26 @@
+/* Test that gmpxx.h compiles correctly.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "gmpxx.h"
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-iostream.cc b/third_party/gmp/tests/cxx/t-iostream.cc
new file mode 100644
index 0000000..76e280b
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-iostream.cc
@@ -0,0 +1,106 @@
+/* Test stream formatted input and output on mp*_class
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include <sstream>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+// The tests are extremely basic. These functions just forward to the
+// ones tested in t-istream.cc and t-ostream.cc; we rely on those for
+// advanced tests and only check the syntax here.
+
+void
+checki ()
+{
+  {
+    istringstream i("123");
+    mpz_class x;
+    i >> x;
+    ASSERT_ALWAYS (x == 123);
+  }
+  {
+    istringstream i("3/4");
+    mpq_class x;
+    i >> x;
+    ASSERT_ALWAYS (x == .75);
+  }
+  {
+    istringstream i("1.5");
+    mpf_class x;
+    i >> x;
+    ASSERT_ALWAYS (x == 1.5);
+  }
+}
+
+void
+checko ()
+{
+  {
+    ostringstream o;
+    mpz_class x=123;
+    o << x;
+    ASSERT_ALWAYS (o.str() == "123");
+  }
+  {
+    ostringstream o;
+    mpz_class x=123;
+    o << (x+1);
+    ASSERT_ALWAYS (o.str() == "124");
+  }
+  {
+    ostringstream o;
+    mpq_class x(3,4);
+    o << x;
+    ASSERT_ALWAYS (o.str() == "3/4");
+  }
+  {
+    ostringstream o;
+    mpq_class x(3,4);
+    o << (x+1);
+    ASSERT_ALWAYS (o.str() == "7/4");
+  }
+  {
+    ostringstream o;
+    mpf_class x=1.5;
+    o << x;
+    ASSERT_ALWAYS (o.str() == "1.5");
+  }
+  {
+    ostringstream o;
+    mpf_class x=1.5;
+    o << (x+1);
+    ASSERT_ALWAYS (o.str() == "2.5");
+  }
+}
+
+int
+main (int argc, char *argv[])
+{
+  tests_start ();
+
+  checki ();
+  checko ();
+
+  tests_end ();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-istream.cc b/third_party/gmp/tests/cxx/t-istream.cc
new file mode 100644
index 0000000..76bcbab
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-istream.cc
@@ -0,0 +1,598 @@
+/* Test istream formatted input.
+
+Copyright 2001-2004 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include <iostream>
+#include <cstdlib>
+#include <cstring>
+
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+// Under option_check_standard, the various test cases for mpz operator>>
+// are put through the standard operator>> for long, and likewise mpf
+// operator>> is put through double.
+//
+// In g++ 3.3 this results in some printouts about the final position
+// indicated for something like ".e123".  Our mpf code stops at the "e"
+// since there's no mantissa digits, but g++ reads the whole thing and only
+// then decides it's bad.
+
+bool option_check_standard = false;
+
+
+// On some versions of g++ 2.96 it's been observed that putback() may leave
+// tellg() unchanged.  We believe this is incorrect and presumably the
+// result of a bug, since for instance it's ok in g++ 2.95 and g++ 3.3.  We
+// detect the problem at runtime and disable affected checks.
+
+bool putback_tellg_works = true;
+
+void
+check_putback_tellg (void)
+{
+  istringstream input ("hello");
+  streampos  old_pos, new_pos;
+  char  c;
+
+  input.get(c);
+  old_pos = input.tellg();
+  input.putback(c);
+  new_pos = input.tellg();
+
+  if (old_pos == new_pos)
+    {
+      cout << "Warning, istringstream has a bug: putback() doesn't update tellg().\n";;
+      cout << "Tests on tellg() will be skipped.\n";
+      putback_tellg_works = false;
+    }
+}
+
+
+#define WRONG(str)                                              \
+  do {                                                          \
+    cout << str ", data[" << i << "]\n";                        \
+    cout << "  input: \"" << data[i].input << "\"\n";           \
+    cout << "  flags: " << hex << input.flags() << dec << "\n"; \
+  } while (0)
+
+void
+check_mpz (void)
+{
+  static const struct {
+    const char     *input;
+    int            want_pos;
+    const char     *want;
+    ios::fmtflags  flags;
+
+  } data[] = {
+
+    { "0",      -1, "0",    (ios::fmtflags) 0 },
+    { "123",    -1, "123",  (ios::fmtflags) 0 },
+    { "0123",   -1, "83",   (ios::fmtflags) 0 },
+    { "0x123",  -1, "291",  (ios::fmtflags) 0 },
+    { "-123",   -1, "-123", (ios::fmtflags) 0 },
+    { "-0123",  -1, "-83",  (ios::fmtflags) 0 },
+    { "-0x123", -1, "-291", (ios::fmtflags) 0 },
+    { "+123",   -1, "123", (ios::fmtflags) 0 },
+    { "+0123",  -1, "83",  (ios::fmtflags) 0 },
+    { "+0x123", -1, "291", (ios::fmtflags) 0 },
+
+    { "0",     -1, "0",    ios::dec },
+    { "1f",     1, "1",    ios::dec },
+    { "011f",   3, "11",   ios::dec },
+    { "123",   -1, "123",  ios::dec },
+    { "-1f",    2, "-1",   ios::dec },
+    { "-011f",  4, "-11",  ios::dec },
+    { "-123",  -1, "-123", ios::dec },
+    { "+1f",    2, "1",    ios::dec },
+    { "+011f",  4, "11",   ios::dec },
+    { "+123",  -1, "123",  ios::dec },
+
+    { "0",    -1, "0",   ios::oct },
+    { "123",  -1, "83",  ios::oct },
+    { "-123", -1, "-83", ios::oct },
+    { "+123", -1, "83",  ios::oct },
+
+    { "0",    -1, "0",    ios::hex },
+    { "123",  -1, "291",  ios::hex },
+    { "ff",   -1, "255",  ios::hex },
+    { "FF",   -1, "255",  ios::hex },
+    { "-123", -1, "-291", ios::hex },
+    { "-ff",  -1, "-255", ios::hex },
+    { "-FF",  -1, "-255", ios::hex },
+    { "+123", -1, "291",  ios::hex },
+    { "+ff",  -1, "255",  ios::hex },
+    { "+FF",  -1, "255",  ios::hex },
+    { "ab",   -1, "171",  ios::hex },
+    { "cd",   -1, "205",  ios::hex },
+    { "ef",   -1, "239",  ios::hex },
+
+    { " 123",  0, NULL,  (ios::fmtflags) 0 },   // not without skipws
+    { " 123", -1, "123", ios::skipws },
+  };
+
+  mpz_t      got, want;
+  bool       got_ok, want_ok;
+  bool       got_eof, want_eof;
+  long       got_si, want_si;
+  streampos  init_tellg, got_pos, want_pos;
+
+  mpz_init (got);
+  mpz_init (want);
+
+  for (size_t i = 0; i < numberof (data); i++)
+    {
+      size_t input_length = strlen (data[i].input);
+      want_pos = (data[i].want_pos == -1
+                  ? input_length : data[i].want_pos);
+      want_eof = (want_pos == streampos(input_length));
+
+      want_ok = (data[i].want != NULL);
+
+      if (data[i].want != NULL)
+        mpz_set_str_or_abort (want, data[i].want, 0);
+      else
+        mpz_set_ui (want, 0L);
+
+      if (option_check_standard && mpz_fits_slong_p (want))
+        {
+          istringstream  input (data[i].input);
+          input.flags (data[i].flags);
+          init_tellg = input.tellg();
+          want_si = mpz_get_si (want);
+
+          input >> got_si;
+          got_ok = !input.fail();
+          got_eof = input.eof();
+          input.clear();
+          got_pos = input.tellg() - init_tellg;
+
+          if (got_ok != want_ok)
+            {
+              WRONG ("stdc++ operator>> wrong status, check_mpz");
+              cout << "  want_ok: " << want_ok << "\n";
+              cout << "  got_ok:  " << got_ok << "\n";
+            }
+          if (want_ok && got_si != want_si)
+            {
+              WRONG ("stdc++ operator>> wrong result, check_mpz");
+              cout << "  got_si:  " << got_si << "\n";
+              cout << "  want_si: " << want_si << "\n";
+            }
+          if (want_ok && got_eof != want_eof)
+            {
+              WRONG ("stdc++ operator>> wrong EOF state, check_mpz");
+              cout << "  got_eof:  " << got_eof << "\n";
+              cout << "  want_eof: " << want_eof << "\n";
+            }
+          if (putback_tellg_works && got_pos != want_pos)
+            {
+              WRONG ("stdc++ operator>> wrong position, check_mpz");
+              cout << "  want_pos: " << want_pos << "\n";
+              cout << "  got_pos:  " << got_pos << "\n";
+            }
+        }
+
+      {
+        istringstream  input (data[i].input);
+        input.flags (data[i].flags);
+        init_tellg = input.tellg();
+
+        mpz_set_ui (got, 0xDEAD);
+        input >> got;
+        got_ok = !input.fail();
+	got_eof = input.eof();
+        input.clear();
+        got_pos = input.tellg() - init_tellg;
+
+        if (got_ok != want_ok)
+          {
+            WRONG ("mpz operator>> wrong status");
+            cout << "  want_ok: " << want_ok << "\n";
+            cout << "  got_ok:  " << got_ok << "\n";
+            abort ();
+          }
+        if (want_ok && mpz_cmp (got, want) != 0)
+          {
+            WRONG ("mpz operator>> wrong result");
+            mpz_trace ("  got ", got);
+            mpz_trace ("  want", want);
+            abort ();
+          }
+        if (want_ok && got_eof != want_eof)
+          {
+            WRONG ("mpz operator>> wrong EOF state");
+            cout << "  want_eof: " << want_eof << "\n";
+            cout << "  got_eof:  " << got_eof << "\n";
+            abort ();
+          }
+        if (putback_tellg_works && got_pos != want_pos)
+          {
+            WRONG ("mpz operator>> wrong position");
+            cout << "  want_pos: " << want_pos << "\n";
+            cout << "  got_pos:  " << got_pos << "\n";
+            abort ();
+          }
+      }
+    }
+
+  mpz_clear (got);
+  mpz_clear (want);
+}
+
+void
+check_mpq (void)
+{
+  static const struct {
+    const char     *input;
+    int            want_pos;
+    const char     *want;
+    ios::fmtflags  flags;
+
+  } data[] = {
+
+    { "0",   -1, "0", (ios::fmtflags) 0 },
+    { "00",  -1, "0", (ios::fmtflags) 0 },
+    { "0x0", -1, "0", (ios::fmtflags) 0 },
+
+    { "123/456",   -1, "123/456", ios::dec },
+    { "0123/456",  -1, "123/456", ios::dec },
+    { "123/0456",  -1, "123/456", ios::dec },
+    { "0123/0456", -1, "123/456", ios::dec },
+
+    { "123/456",   -1, "83/302", ios::oct },
+    { "0123/456",  -1, "83/302", ios::oct },
+    { "123/0456",  -1, "83/302", ios::oct },
+    { "0123/0456", -1, "83/302", ios::oct },
+
+    { "ab",   -1, "171",  ios::hex },
+    { "cd",   -1, "205",  ios::hex },
+    { "ef",   -1, "239",  ios::hex },
+
+    { "0/0",     -1, "0/0", (ios::fmtflags) 0 },
+    { "5/8",     -1, "5/8", (ios::fmtflags) 0 },
+    { "0x5/0x8", -1, "5/8", (ios::fmtflags) 0 },
+
+    { "123/456",   -1, "123/456",  (ios::fmtflags) 0 },
+    { "123/0456",  -1, "123/302",  (ios::fmtflags) 0 },
+    { "123/0x456", -1, "123/1110", (ios::fmtflags) 0 },
+    { "123/0X456", -1, "123/1110", (ios::fmtflags) 0 },
+
+    { "0123/123",   -1, "83/123", (ios::fmtflags) 0 },
+    { "0123/0123",  -1, "83/83",  (ios::fmtflags) 0 },
+    { "0123/0x123", -1, "83/291", (ios::fmtflags) 0 },
+    { "0123/0X123", -1, "83/291", (ios::fmtflags) 0 },
+
+    { "0x123/123",   -1, "291/123", (ios::fmtflags) 0 },
+    { "0X123/0123",  -1, "291/83",  (ios::fmtflags) 0 },
+    { "0x123/0x123", -1, "291/291", (ios::fmtflags) 0 },
+
+    { " 123",  0, NULL,  (ios::fmtflags) 0 },   // not without skipws
+    { " 123", -1, "123", ios::skipws },
+
+    { "123 /456",    3, "123",  (ios::fmtflags) 0 },
+    { "123/ 456",    4,  NULL,  (ios::fmtflags) 0 },
+    { "123/"    ,   -1,  NULL,  (ios::fmtflags) 0 },
+    { "123 /456",    3, "123",  ios::skipws },
+    { "123/ 456",    4,  NULL,  ios::skipws },
+  };
+
+  mpq_t      got, want;
+  bool       got_ok, want_ok;
+  bool       got_eof, want_eof;
+  long       got_si, want_si;
+  streampos  init_tellg, got_pos, want_pos;
+
+  mpq_init (got);
+  mpq_init (want);
+
+  for (size_t i = 0; i < numberof (data); i++)
+    {
+      size_t input_length = strlen (data[i].input);
+      want_pos = (data[i].want_pos == -1
+                  ? input_length : data[i].want_pos);
+      want_eof = (want_pos == streampos(input_length));
+
+      want_ok = (data[i].want != NULL);
+
+      if (data[i].want != NULL)
+        mpq_set_str_or_abort (want, data[i].want, 0);
+      else
+        mpq_set_ui (want, 0L, 1L);
+
+      if (option_check_standard
+          && mpz_fits_slong_p (mpq_numref(want))
+          && mpz_cmp_ui (mpq_denref(want), 1L) == 0
+          && strchr (data[i].input, '/') == NULL)
+        {
+          istringstream  input (data[i].input);
+          input.flags (data[i].flags);
+          init_tellg = input.tellg();
+          want_si = mpz_get_si (mpq_numref(want));
+
+          input >> got_si;
+          got_ok = !input.fail();
+          got_eof = input.eof();
+          input.clear();
+          got_pos = input.tellg() - init_tellg;
+
+          if (got_ok != want_ok)
+            {
+              WRONG ("stdc++ operator>> wrong status, check_mpq");
+              cout << "  want_ok: " << want_ok << "\n";
+              cout << "  got_ok:  " << got_ok << "\n";
+            }
+          if (want_ok && want_si != got_si)
+            {
+              WRONG ("stdc++ operator>> wrong result, check_mpq");
+              cout << "  got_si:  " << got_si << "\n";
+              cout << "  want_si: " << want_si << "\n";
+            }
+          if (want_ok && got_eof != want_eof)
+            {
+              WRONG ("stdc++ operator>> wrong EOF state, check_mpq");
+              cout << "  got_eof:  " << got_eof << "\n";
+              cout << "  want_eof: " << want_eof << "\n";
+            }
+          if (putback_tellg_works && got_pos != want_pos)
+            {
+              WRONG ("stdc++ operator>> wrong position, check_mpq");
+              cout << "  want_pos: " << want_pos << "\n";
+              cout << "  got_pos:  " << got_pos << "\n";
+            }
+        }
+
+      {
+        istringstream  input (data[i].input);
+        input.flags (data[i].flags);
+        init_tellg = input.tellg();
+        mpq_set_si (got, 0xDEAD, 0xBEEF);
+
+        input >> got;
+        got_ok = !input.fail();
+	got_eof = input.eof();
+        input.clear();
+        got_pos = input.tellg() - init_tellg;
+
+        if (got_ok != want_ok)
+          {
+            WRONG ("mpq operator>> wrong status");
+            cout << "  want_ok: " << want_ok << "\n";
+            cout << "  got_ok:  " << got_ok << "\n";
+            abort ();
+          }
+        // don't use mpq_equal, since we allow non-normalized values to be
+        // read, which can trigger ASSERTs in mpq_equal
+        if (want_ok && (mpz_cmp (mpq_numref (got), mpq_numref(want)) != 0
+                        || mpz_cmp (mpq_denref (got), mpq_denref(want)) != 0))
+          {
+            WRONG ("mpq operator>> wrong result");
+            mpq_trace ("  got ", got);
+            mpq_trace ("  want", want);
+            abort ();
+          }
+        if (want_ok && got_eof != want_eof)
+          {
+            WRONG ("mpq operator>> wrong EOF state");
+            cout << "  want_eof: " << want_eof << "\n";
+            cout << "  got_eof:  " << got_eof << "\n";
+            abort ();
+          }
+        if (putback_tellg_works && got_pos != want_pos)
+          {
+            WRONG ("mpq operator>> wrong position");
+            cout << "  want_pos: " << want_pos << "\n";
+            cout << "  got_pos:  " << got_pos << "\n";
+            abort ();
+          }
+      }
+    }
+
+  mpq_clear (got);
+  mpq_clear (want);
+}
+
+
+void
+check_mpf (void)
+{
+  static const struct {
+    const char     *input;
+    int            want_pos;
+    const char     *want;
+    ios::fmtflags  flags;
+
+  } data[] = {
+
+    { "0",      -1, "0", (ios::fmtflags) 0 },
+    { "+0",     -1, "0", (ios::fmtflags) 0 },
+    { "-0",     -1, "0", (ios::fmtflags) 0 },
+    { "0.0",    -1, "0", (ios::fmtflags) 0 },
+    { "0.",     -1, "0", (ios::fmtflags) 0 },
+    { ".0",     -1, "0", (ios::fmtflags) 0 },
+    { "+.0",    -1, "0", (ios::fmtflags) 0 },
+    { "-.0",    -1, "0", (ios::fmtflags) 0 },
+    { "+0.00",  -1, "0", (ios::fmtflags) 0 },
+    { "-0.000", -1, "0", (ios::fmtflags) 0 },
+    { "+0.00",  -1, "0", (ios::fmtflags) 0 },
+    { "-0.000", -1, "0", (ios::fmtflags) 0 },
+    { "0.0e0",  -1, "0", (ios::fmtflags) 0 },
+    { "0.e0",   -1, "0", (ios::fmtflags) 0 },
+    { ".0e0",   -1, "0", (ios::fmtflags) 0 },
+    { "0.0e-0", -1, "0", (ios::fmtflags) 0 },
+    { "0.e-0",  -1, "0", (ios::fmtflags) 0 },
+    { ".0e-0",  -1, "0", (ios::fmtflags) 0 },
+    { "0.0e+0", -1, "0", (ios::fmtflags) 0 },
+    { "0.e+0",  -1, "0", (ios::fmtflags) 0 },
+    { ".0e+0",  -1, "0", (ios::fmtflags) 0 },
+
+    { "1",  -1,  "1", (ios::fmtflags) 0 },
+    { "+1", -1,  "1", (ios::fmtflags) 0 },
+    { "-1", -1, "-1", (ios::fmtflags) 0 },
+
+    { " 0",  0,  NULL, (ios::fmtflags) 0 },  // not without skipws
+    { " 0",  -1, "0", ios::skipws },
+    { " +0", -1, "0", ios::skipws },
+    { " -0", -1, "0", ios::skipws },
+
+    { "+-123", 1, NULL, (ios::fmtflags) 0 },
+    { "-+123", 1, NULL, (ios::fmtflags) 0 },
+    { "1e+-123", 3, NULL, (ios::fmtflags) 0 },
+    { "1e-+123", 3, NULL, (ios::fmtflags) 0 },
+
+    { "e123",   0, NULL, (ios::fmtflags) 0 }, // at least one mantissa digit
+    { ".e123",  1, NULL, (ios::fmtflags) 0 },
+    { "+.e123", 2, NULL, (ios::fmtflags) 0 },
+    { "-.e123", 2, NULL, (ios::fmtflags) 0 },
+
+    { "123e",   4, NULL, (ios::fmtflags) 0 }, // at least one exponent digit
+    { "123e-",  5, NULL, (ios::fmtflags) 0 },
+    { "123e+",  5, NULL, (ios::fmtflags) 0 },
+  };
+
+  mpf_t      got, want;
+  bool       got_ok, want_ok;
+  bool       got_eof, want_eof;
+  double     got_d, want_d;
+  streampos  init_tellg, got_pos, want_pos;
+
+  mpf_init (got);
+  mpf_init (want);
+
+  for (size_t i = 0; i < numberof (data); i++)
+    {
+      size_t input_length = strlen (data[i].input);
+      want_pos = (data[i].want_pos == -1
+                  ? input_length : data[i].want_pos);
+      want_eof = (want_pos == streampos(input_length));
+
+      want_ok = (data[i].want != NULL);
+
+      if (data[i].want != NULL)
+        mpf_set_str_or_abort (want, data[i].want, 0);
+      else
+        mpf_set_ui (want, 0L);
+
+      want_d = mpf_get_d (want);
+      if (option_check_standard && mpf_cmp_d (want, want_d) == 0)
+        {
+          istringstream  input (data[i].input);
+          input.flags (data[i].flags);
+          init_tellg = input.tellg();
+
+          input >> got_d;
+          got_ok = !input.fail();
+          got_eof = input.eof();
+          input.clear();
+          got_pos = input.tellg() - init_tellg;
+
+          if (got_ok != want_ok)
+            {
+              WRONG ("stdc++ operator>> wrong status, check_mpf");
+              cout << "  want_ok: " << want_ok << "\n";
+              cout << "  got_ok:  " << got_ok << "\n";
+            }
+          if (want_ok && want_d != got_d)
+            {
+              WRONG ("stdc++ operator>> wrong result, check_mpf");
+              cout << "  got:   " << got_d << "\n";
+              cout << "  want:  " << want_d << "\n";
+            }
+          if (want_ok && got_eof != want_eof)
+            {
+              WRONG ("stdc++ operator>> wrong EOF state, check_mpf");
+              cout << "  got_eof:  " << got_eof << "\n";
+              cout << "  want_eof: " << want_eof << "\n";
+            }
+          if (putback_tellg_works && got_pos != want_pos)
+            {
+              WRONG ("stdc++ operator>> wrong position, check_mpf");
+              cout << "  want_pos: " << want_pos << "\n";
+              cout << "  got_pos:  " << got_pos << "\n";
+            }
+        }
+
+      {
+        istringstream  input (data[i].input);
+        input.flags (data[i].flags);
+        init_tellg = input.tellg();
+
+        mpf_set_ui (got, 0xDEAD);
+        input >> got;
+        got_ok = !input.fail();
+	got_eof = input.eof();
+        input.clear();
+        got_pos = input.tellg() - init_tellg;
+
+        if (got_ok != want_ok)
+          {
+            WRONG ("mpf operator>> wrong status");
+            cout << "  want_ok: " << want_ok << "\n";
+            cout << "  got_ok:  " << got_ok << "\n";
+            abort ();
+          }
+        if (want_ok && mpf_cmp (got, want) != 0)
+          {
+            WRONG ("mpf operator>> wrong result");
+            mpf_trace ("  got ", got);
+            mpf_trace ("  want", want);
+            abort ();
+          }
+        if (want_ok && got_eof != want_eof)
+          {
+            WRONG ("mpf operator>> wrong EOF state");
+            cout << "  want_eof: " << want_eof << "\n";
+            cout << "  got_eof:  " << got_eof << "\n";
+            abort ();
+          }
+        if (putback_tellg_works && got_pos != want_pos)
+          {
+            WRONG ("mpf operator>> wrong position");
+            cout << "  want_pos: " << want_pos << "\n";
+            cout << "  got_pos:  " << got_pos << "\n";
+            abort ();
+          }
+      }
+    }
+
+  mpf_clear (got);
+  mpf_clear (want);
+}
+
+
+
+int
+main (int argc, char *argv[])
+{
+  if (argc > 1 && strcmp (argv[1], "-s") == 0)
+    option_check_standard = true;
+
+  tests_start ();
+
+  check_putback_tellg ();
+  check_mpz ();
+  check_mpq ();
+  check_mpf ();
+
+  tests_end ();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-locale.cc b/third_party/gmp/tests/cxx/t-locale.cc
new file mode 100644
index 0000000..14e95e0
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-locale.cc
@@ -0,0 +1,194 @@
+/* Test locale support in C++ functions.
+
+Copyright 2001-2003, 2007 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include <clocale>
+#include <iostream>
+#include <cstdlib>
+
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+extern "C" {
+  char point_string[2];
+}
+
+#if HAVE_STD__LOCALE
+// Like std::numpunct, but with decimal_point coming from point_string[].
+class my_numpunct : public numpunct<char> {
+ public:
+  explicit my_numpunct (size_t r = 0) : numpunct<char>(r) { }
+ protected:
+  char do_decimal_point() const { return point_string[0]; }
+};
+#endif
+
+void
+set_point (char c)
+{
+  point_string[0] = c;
+
+#if HAVE_STD__LOCALE
+  locale loc (locale::classic(), new my_numpunct ());
+  locale::global (loc);
+#endif
+}
+
+
+void
+check_input (void)
+{
+  static const struct {
+    const char  *str1;
+    const char  *str2;
+    double      want;
+  } data[] = {
+
+    { "1","",   1.0 },
+    { "1","0",  1.0 },
+    { "1","00", 1.0 },
+
+    { "","5",    0.5 },
+    { "0","5",   0.5 },
+    { "00","5",  0.5 },
+    { "00","50", 0.5 },
+
+    { "1","5",    1.5 },
+    { "1","5e1", 15.0 },
+  };
+
+  static char point[] = {
+    '.', ',', 'x', '\xFF'
+  };
+
+  mpf_t  got;
+  mpf_init (got);
+
+  for (size_t i = 0; i < numberof (point); i++)
+    {
+      set_point (point[i]);
+
+      for (int neg = 0; neg <= 1; neg++)
+        {
+          for (size_t j = 0; j < numberof (data); j++)
+            {
+              string str = string(data[j].str1)+point[i]+string(data[j].str2);
+              if (neg)
+                str = "-" + str;
+
+              istringstream is (str.c_str());
+
+              mpf_set_ui (got, 123);   // dummy initial value
+
+              if (! (is >> got))
+                {
+                  cout << "istream mpf_t operator>> error\n";
+                  cout << "  point " << point[i] << "\n";
+                  cout << "  str   \"" << str << "\"\n";
+                  cout << "  localeconv point \""
+                       << GMP_DECIMAL_POINT << "\"\n";
+                  abort ();
+                }
+
+              double want = data[j].want;
+              if (neg)
+                want = -want;
+              if (mpf_cmp_d (got, want) != 0)
+                {
+                  cout << "istream mpf_t operator>> wrong\n";
+                  cout << "  point " << point[i] << "\n";
+                  cout << "  str   \"" << str << "\"\n";
+                  cout << "  got   " << got << "\n";
+                  cout << "  want  " << want << "\n";
+                  cout << "  localeconv point \""
+                       << GMP_DECIMAL_POINT << "\"\n";
+                  abort ();
+                }
+            }
+        }
+    }
+
+  mpf_clear (got);
+}
+
+void
+check_output (void)
+{
+  static char point[] = {
+    '.', ',', 'x', '\xFF'
+  };
+
+  for (size_t i = 0; i < numberof (point); i++)
+    {
+      set_point (point[i]);
+      ostringstream  got;
+
+      mpf_t  f;
+      mpf_init (f);
+      mpf_set_d (f, 1.5);
+      got << f;
+      mpf_clear (f);
+
+      string  want = string("1") + point[i] + string("5");
+
+      if (want.compare (got.str()) != 0)
+        {
+          cout << "ostream mpf_t operator<< doesn't respect locale\n";
+          cout << "  point " << point[i] << "\n";
+          cout << "  got   \"" << got.str() << "\"\n";
+          cout << "  want  \"" << want      << "\"\n";
+          abort ();
+        }
+    }
+}
+
+int
+replacement_works (void)
+{
+  set_point ('x');
+  mpf_t  f;
+  mpf_init (f);
+  mpf_set_d (f, 1.5);
+  ostringstream s;
+  s << f;
+  mpf_clear (f);
+
+  return (s.str().compare("1x5") == 0);
+}
+
+int
+main (void)
+{
+  tests_start ();
+
+  if (replacement_works())
+    {
+      check_input ();
+      check_output ();
+    }
+  else
+    {
+      cout << "Replacing decimal point didn't work, tests skipped\n";
+    }
+
+  tests_end ();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-misc.cc b/third_party/gmp/tests/cxx/t-misc.cc
new file mode 100644
index 0000000..1143e84
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-misc.cc
@@ -0,0 +1,397 @@
+/* Test mp*_class functions.
+
+Copyright 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+
+/* Note that we don't use <climits> for LONG_MIN, but instead our own
+   definitions in gmp-impl.h.  In g++ 2.95.4 (debian 3.0) under
+   -mcpu=ultrasparc, limits.h sees __sparc_v9__ defined and assumes that
+   means long is 64-bit long, but it's only 32-bits, causing fatal compile
+   errors.  */
+
+#include "config.h"
+
+#include <string>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+void
+check_mpz (void)
+{
+  // mpz_class::fits_sint_p
+  {
+    bool       fits;
+    mpz_class  z;
+    z = INT_MIN; fits = z.fits_sint_p(); ASSERT_ALWAYS (fits);
+    z--;         fits = z.fits_sint_p(); ASSERT_ALWAYS (! fits);
+    z = INT_MAX; fits = z.fits_sint_p(); ASSERT_ALWAYS (fits);
+    z++;         fits = z.fits_sint_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpz_class::fits_uint_p
+  {
+    bool       fits;
+    mpz_class  z;
+    z = 0;        fits = z.fits_uint_p(); ASSERT_ALWAYS (fits);
+    z--;          fits = z.fits_uint_p(); ASSERT_ALWAYS (! fits);
+    z = UINT_MAX; fits = z.fits_uint_p(); ASSERT_ALWAYS (fits);
+    z++;          fits = z.fits_uint_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpz_class::fits_slong_p
+  {
+    bool       fits;
+    mpz_class  z;
+    z = LONG_MIN; fits = z.fits_slong_p(); ASSERT_ALWAYS (fits);
+    z--;          fits = z.fits_slong_p(); ASSERT_ALWAYS (! fits);
+    z = LONG_MAX; fits = z.fits_slong_p(); ASSERT_ALWAYS (fits);
+    z++;          fits = z.fits_slong_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpz_class::fits_ulong_p
+  {
+    bool       fits;
+    mpz_class  z;
+    z = 0;         fits = z.fits_ulong_p(); ASSERT_ALWAYS (fits);
+    z--;           fits = z.fits_ulong_p(); ASSERT_ALWAYS (! fits);
+    z = ULONG_MAX; fits = z.fits_ulong_p(); ASSERT_ALWAYS (fits);
+    z++;           fits = z.fits_ulong_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpz_class::fits_sshort_p
+  {
+    bool       fits;
+    mpz_class  z;
+    z = SHRT_MIN; fits = z.fits_sshort_p(); ASSERT_ALWAYS (fits);
+    z--;          fits = z.fits_sshort_p(); ASSERT_ALWAYS (! fits);
+    z = SHRT_MAX; fits = z.fits_sshort_p(); ASSERT_ALWAYS (fits);
+    z++;          fits = z.fits_sshort_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpz_class::fits_ushort_p
+  {
+    bool       fits;
+    mpz_class  z;
+    z = 0;         fits = z.fits_ushort_p(); ASSERT_ALWAYS (fits);
+    z--;           fits = z.fits_ushort_p(); ASSERT_ALWAYS (! fits);
+    z = USHRT_MAX; fits = z.fits_ushort_p(); ASSERT_ALWAYS (fits);
+    z++;           fits = z.fits_ushort_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpz_class::get_mpz_t
+  {
+    mpz_class  z(0);
+    mpz_ptr    p = z.get_mpz_t();
+    ASSERT_ALWAYS (mpz_cmp_ui (p, 0) == 0);
+  }
+  {
+    mpz_class  z(0);
+    mpz_srcptr p = z.get_mpz_t();
+    ASSERT_ALWAYS (mpz_cmp_ui (p, 0) == 0);
+  }
+
+  // mpz_class::get_d
+  // mpz_class::get_si
+  // mpz_class::get_ui
+  {
+    mpz_class  z(123);
+    { double d = z.get_d();  ASSERT_ALWAYS (d == 123.0); }
+    { long   l = z.get_si(); ASSERT_ALWAYS (l == 123L); }
+    { long   u = z.get_ui(); ASSERT_ALWAYS (u == 123L); }
+  }
+  {
+    mpz_class  z(-123);
+    { double d = z.get_d();  ASSERT_ALWAYS (d == -123.0); }
+    { long   l = z.get_si(); ASSERT_ALWAYS (l == -123L); }
+  }
+
+  // mpz_class::get_str
+  {
+    mpz_class  z(123);
+    string     s;
+    s = z.get_str(); ASSERT_ALWAYS (s == "123");
+    s = z.get_str(16); ASSERT_ALWAYS (s == "7b");
+    s = z.get_str(-16); ASSERT_ALWAYS (s == "7B");
+  }
+
+  // mpz_class::set_str
+  {
+    mpz_class  z;
+    int        ret;
+    ret = z.set_str ("123", 10);  ASSERT_ALWAYS (ret == 0 && z == 123);
+    ret = z.set_str ("7b",  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
+    ret = z.set_str ("7B",  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
+    ret = z.set_str ("0x7B", 0);  ASSERT_ALWAYS (ret == 0 && z == 123);
+
+    ret = z.set_str (string("123"), 10);  ASSERT_ALWAYS (ret == 0 && z == 123);
+    ret = z.set_str (string("7b"),  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
+    ret = z.set_str (string("7B"),  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
+    ret = z.set_str (string("0x7B"), 0);  ASSERT_ALWAYS (ret == 0 && z == 123);
+  }
+}
+
+void
+check_mpq (void)
+{
+  // mpq_class::canonicalize
+  {
+    mpq_class  q(12,9);
+    q.canonicalize();
+    ASSERT_ALWAYS (q.get_num() == 4);
+    ASSERT_ALWAYS (q.get_den() == 3);
+  }
+
+  // mpq_class::get_d
+  {
+    mpq_class  q(123);
+    { double d = q.get_d();  ASSERT_ALWAYS (d == 123.0); }
+  }
+  {
+    mpq_class  q(-123);
+    { double d = q.get_d();  ASSERT_ALWAYS (d == -123.0); }
+  }
+
+  // mpq_class::get_mpq_t
+  {
+    mpq_class  q(0);
+    mpq_ptr    p = q.get_mpq_t();
+    ASSERT_ALWAYS (mpq_cmp_ui (p, 0, 1) == 0);
+  }
+  {
+    mpq_class  q(0);
+    mpq_srcptr p = q.get_mpq_t();
+    ASSERT_ALWAYS (mpq_cmp_ui (p, 0, 1) == 0);
+  }
+
+  // mpq_class::get_num, mpq_class::get_den
+  {
+    const mpq_class  q(4,5);
+    mpz_class  z;
+    z = q.get_num(); ASSERT_ALWAYS (z == 4);
+    z = q.get_den(); ASSERT_ALWAYS (z == 5);
+  }
+
+  // mpq_class::get_num_mpz_t, mpq_class::get_den_mpz_t
+  {
+    mpq_class  q(4,5);
+    mpz_ptr    p;
+    p = q.get_num_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 4) == 0);
+    p = q.get_den_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 5) == 0);
+  }
+  {
+    const mpq_class  q(4,5);
+    mpz_srcptr p;
+    p = q.get_num_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 4) == 0);
+    p = q.get_den_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 5) == 0);
+  }
+
+  // mpq_class::get_str
+  {
+    mpq_class  q(17,11);
+    string     s;
+    s = q.get_str();    ASSERT_ALWAYS (s == "17/11");
+    s = q.get_str(10);  ASSERT_ALWAYS (s == "17/11");
+    s = q.get_str(16);  ASSERT_ALWAYS (s == "11/b");
+    s = q.get_str(-16); ASSERT_ALWAYS (s == "11/B");
+  }
+
+  // mpq_class::set_str
+  {
+    mpq_class  q;
+    int        ret;
+    ret = q.set_str ("123", 10);     ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str ("4/5", 10);     ASSERT_ALWAYS (ret == 0 && q == mpq_class(4,5));
+    ret = q.set_str ("7b",  16);     ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str ("7B",  16);     ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str ("0x7B", 0);     ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str ("0x10/17", 0);  ASSERT_ALWAYS (ret == 0 && q == mpq_class(16,17));
+
+    ret = q.set_str (string("4/5"), 10);  ASSERT_ALWAYS (ret == 0 && q == mpq_class(4,5));
+    ret = q.set_str (string("123"), 10);  ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str (string("7b"),  16);  ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str (string("7B"),  16);  ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str (string("0x7B"), 0);  ASSERT_ALWAYS (ret == 0 && q == 123);
+    ret = q.set_str (string("0x10/17"), 0);  ASSERT_ALWAYS (ret == 0 && q == mpq_class(16,17));
+  }
+}
+
+void
+check_mpf (void)
+{
+  // mpf_class::fits_sint_p
+  {
+    bool       fits;
+    mpf_class  f (0, 2*8*sizeof(int));
+    f = INT_MIN; fits = f.fits_sint_p(); ASSERT_ALWAYS (fits);
+    f--;         fits = f.fits_sint_p(); ASSERT_ALWAYS (! fits);
+    f = INT_MAX; fits = f.fits_sint_p(); ASSERT_ALWAYS (fits);
+    f++;         fits = f.fits_sint_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpf_class::fits_uint_p
+  {
+    bool       fits;
+    mpf_class  f (0, 2*8*sizeof(int));
+    f = 0;        fits = f.fits_uint_p(); ASSERT_ALWAYS (fits);
+    f--;          fits = f.fits_uint_p(); ASSERT_ALWAYS (! fits);
+    f = UINT_MAX; fits = f.fits_uint_p(); ASSERT_ALWAYS (fits);
+    f++;          fits = f.fits_uint_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpf_class::fits_slong_p
+  {
+    bool       fits;
+    mpf_class  f (0, 2*8*sizeof(long));
+    f = LONG_MIN; fits = f.fits_slong_p(); ASSERT_ALWAYS (fits);
+    f--;          fits = f.fits_slong_p(); ASSERT_ALWAYS (! fits);
+    f = LONG_MAX; fits = f.fits_slong_p(); ASSERT_ALWAYS (fits);
+    f++;          fits = f.fits_slong_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpf_class::fits_ulong_p
+  {
+    bool       fits;
+    mpf_class  f (0, 2*8*sizeof(long));
+    f = 0;         fits = f.fits_ulong_p(); ASSERT_ALWAYS (fits);
+    f--;           fits = f.fits_ulong_p(); ASSERT_ALWAYS (! fits);
+    f = ULONG_MAX; fits = f.fits_ulong_p(); ASSERT_ALWAYS (fits);
+    f++;           fits = f.fits_ulong_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpf_class::fits_sshort_p
+  {
+    bool       fits;
+    mpf_class  f (0, 2*8*sizeof(short));
+    f = SHRT_MIN; fits = f.fits_sshort_p(); ASSERT_ALWAYS (fits);
+    f--;          fits = f.fits_sshort_p(); ASSERT_ALWAYS (! fits);
+    f = SHRT_MAX; fits = f.fits_sshort_p(); ASSERT_ALWAYS (fits);
+    f++;          fits = f.fits_sshort_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpf_class::fits_ushort_p
+  {
+    bool       fits;
+    mpf_class  f (0, 2*8*sizeof(short));
+    f = 0;         fits = f.fits_ushort_p(); ASSERT_ALWAYS (fits);
+    f--;           fits = f.fits_ushort_p(); ASSERT_ALWAYS (! fits);
+    f = USHRT_MAX; fits = f.fits_ushort_p(); ASSERT_ALWAYS (fits);
+    f++;           fits = f.fits_ushort_p(); ASSERT_ALWAYS (! fits);
+  }
+
+  // mpf_class::get_d
+  // mpf_class::get_si
+  // mpf_class::get_ui
+  {
+    mpf_class  f(123);
+    { double d = f.get_d();  ASSERT_ALWAYS (d == 123.0); }
+    { long   l = f.get_si(); ASSERT_ALWAYS (l == 123L); }
+    { long   u = f.get_ui(); ASSERT_ALWAYS (u == 123L); }
+  }
+  {
+    mpf_class  f(-123);
+    { double d = f.get_d();  ASSERT_ALWAYS (d == -123.0); }
+    { long   l = f.get_si(); ASSERT_ALWAYS (l == -123L); }
+  }
+
+  // mpf_class::get_prec
+  {
+    mpf_class  f;
+    ASSERT_ALWAYS (f.get_prec() == mpf_get_default_prec());
+  }
+
+  // mpf_class::get_str
+  {
+    mpf_class  f(123);
+    string     s;
+    mp_exp_t   e;
+    s = f.get_str(e);        ASSERT_ALWAYS (s == "123" && e == 3);
+    s = f.get_str(e,  16);   ASSERT_ALWAYS (s == "7b"  && e == 2);
+    s = f.get_str(e, -16);   ASSERT_ALWAYS (s == "7B"  && e == 2);
+    s = f.get_str(e, 10, 2); ASSERT_ALWAYS (s == "12"  && e == 3);
+    s = f.get_str(e, 10, 1); ASSERT_ALWAYS (s == "1"   && e == 3);
+  }
+
+  // mpf_class::set_str
+  {
+    mpf_class  f;
+    int        ret;
+    ret = f.set_str ("123",     10);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str ("123e1",   10);  ASSERT_ALWAYS (ret == 0 && f == 1230);
+    ret = f.set_str ("1230e-1", 10);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str ("7b",      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str ("7B",      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str ("7B@1",    16);  ASSERT_ALWAYS (ret == 0 && f == 1968);
+    ret = f.set_str ("7B0@-1",  16);  ASSERT_ALWAYS (ret == 0 && f == 123);
+
+    ret = f.set_str (string("123"),     10);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str (string("123e1"),   10);  ASSERT_ALWAYS (ret == 0 && f == 1230);
+    ret = f.set_str (string("1230e-1"), 10);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str (string("7b"),      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str (string("7B"),      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
+    ret = f.set_str (string("7B@1"),    16);  ASSERT_ALWAYS (ret == 0 && f == 1968);
+    ret = f.set_str (string("7B0@-1"),  16);  ASSERT_ALWAYS (ret == 0 && f == 123);
+  }
+
+  // mpf_class::set_prec
+  {
+    mpf_class  f;
+    f.set_prec (256);
+    ASSERT_ALWAYS (f.get_prec () >= 256);
+  }
+
+  // mpf_class::set_prec_raw
+  {
+    mpf_class  f (0, 100 * GMP_NUMB_BITS);
+    f.set_prec_raw (5 * GMP_NUMB_BITS);
+    ASSERT_ALWAYS (f.get_prec () >= 5 * GMP_NUMB_BITS);
+    ASSERT_ALWAYS (f.get_prec () < 100 * GMP_NUMB_BITS);
+    f.set_prec_raw (100 * GMP_NUMB_BITS);
+  }
+}
+
+// std::numeric_limits
+void
+check_limits (void)
+{
+  // Check that the content is not private.
+  ASSERT_ALWAYS ( std::numeric_limits<mpz_class>::is_integer);
+  ASSERT_ALWAYS (!std::numeric_limits<mpf_class>::is_integer);
+
+  // Check that symbols are emitted.
+  ASSERT_ALWAYS (&std::numeric_limits<mpz_class>::is_integer
+	      != &std::numeric_limits<mpq_class>::is_integer);
+}
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpz();
+  check_mpq();
+  check_mpf();
+  check_limits();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-mix.cc b/third_party/gmp/tests/cxx/t-mix.cc
new file mode 100644
index 0000000..cb6733b
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-mix.cc
@@ -0,0 +1,82 @@
+/* Test legality of conversion between the different mp*_class
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+int f_z  (mpz_class){return 0;}
+int f_q  (mpq_class){return 1;}
+int f_f  (mpf_class){return 2;}
+int f_zq (mpz_class){return 0;}
+int f_zq (mpq_class){return 1;}
+int f_zf (mpz_class){return 0;}
+int f_zf (mpf_class){return 2;}
+int f_qf (mpq_class){return 1;}
+int f_qf (mpf_class){return 2;}
+int f_zqf(mpz_class){return 0;}
+int f_zqf(mpq_class){return 1;}
+int f_zqf(mpf_class){return 2;}
+
+void
+check (void)
+{
+  mpz_class z=42;
+  mpq_class q=33;
+  mpf_class f=18;
+
+  ASSERT_ALWAYS(f_z  (z)==0); ASSERT_ALWAYS(f_z  (-z)==0);
+  ASSERT_ALWAYS(f_q  (z)==1); ASSERT_ALWAYS(f_q  (-z)==1);
+  ASSERT_ALWAYS(f_q  (q)==1); ASSERT_ALWAYS(f_q  (-q)==1);
+  ASSERT_ALWAYS(f_f  (z)==2); ASSERT_ALWAYS(f_f  (-z)==2);
+  ASSERT_ALWAYS(f_f  (q)==2); ASSERT_ALWAYS(f_f  (-q)==2);
+  ASSERT_ALWAYS(f_f  (f)==2); ASSERT_ALWAYS(f_f  (-f)==2);
+  ASSERT_ALWAYS(f_zq (z)==0);
+  ASSERT_ALWAYS(f_zq (q)==1); ASSERT_ALWAYS(f_zq (-q)==1);
+  ASSERT_ALWAYS(f_zf (z)==0);
+  ASSERT_ALWAYS(f_zf (f)==2); ASSERT_ALWAYS(f_zf (-f)==2);
+  ASSERT_ALWAYS(f_qf (q)==1);
+  ASSERT_ALWAYS(f_qf (f)==2); ASSERT_ALWAYS(f_qf (-f)==2);
+  ASSERT_ALWAYS(f_zqf(z)==0);
+  ASSERT_ALWAYS(f_zqf(q)==1);
+  ASSERT_ALWAYS(f_zqf(f)==2); ASSERT_ALWAYS(f_zqf(-f)==2);
+
+  ASSERT_ALWAYS(f_zqf(mpz_class(z))==0); ASSERT_ALWAYS(f_zqf(mpz_class(-z))==0);
+  ASSERT_ALWAYS(f_zqf(mpz_class(q))==0); ASSERT_ALWAYS(f_zqf(mpz_class(-q))==0);
+  ASSERT_ALWAYS(f_zqf(mpz_class(f))==0); ASSERT_ALWAYS(f_zqf(mpz_class(-f))==0);
+  ASSERT_ALWAYS(f_zqf(mpq_class(z))==1); ASSERT_ALWAYS(f_zqf(mpq_class(-z))==1);
+  ASSERT_ALWAYS(f_zqf(mpq_class(q))==1); ASSERT_ALWAYS(f_zqf(mpq_class(-q))==1);
+  ASSERT_ALWAYS(f_zqf(mpq_class(f))==1); ASSERT_ALWAYS(f_zqf(mpq_class(-f))==1);
+  ASSERT_ALWAYS(f_zqf(mpf_class(z))==2); ASSERT_ALWAYS(f_zqf(mpf_class(-z))==2);
+  ASSERT_ALWAYS(f_zqf(mpf_class(q))==2); ASSERT_ALWAYS(f_zqf(mpf_class(-q))==2);
+  ASSERT_ALWAYS(f_zqf(mpf_class(f))==2); ASSERT_ALWAYS(f_zqf(mpf_class(-f))==2);
+}
+
+int
+main (void)
+{
+  tests_start();
+
+  check();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-ops.cc b/third_party/gmp/tests/cxx/t-ops.cc
new file mode 100644
index 0000000..ecc6bd0
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ops.cc
@@ -0,0 +1,753 @@
+/* Test mp*_class operators and functions.
+
+Copyright 2001-2003, 2015 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <iostream>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+void
+check_mpz (void)
+{
+  // unary operators and functions
+
+  // operator+
+  {
+    mpz_class a(1);
+    mpz_class b;
+    b = +a; ASSERT_ALWAYS(b == 1);
+  }
+
+  // operator-
+  {
+    mpz_class a(2);
+    mpz_class b;
+    b = -a; ASSERT_ALWAYS(b == -2);
+  }
+
+  // operator~
+  {
+    mpz_class a(3);
+    mpz_class b;
+    b = ~a; ASSERT_ALWAYS(b == -4);
+  }
+
+  // abs
+  {
+    mpz_class a(-123);
+    mpz_class b;
+    b = abs(a); ASSERT_ALWAYS(b == 123);
+    a <<= 300;
+    b = abs(a); ASSERT_ALWAYS(a + b == 0);
+  }
+
+  // sqrt
+  {
+    mpz_class a(25);
+    mpz_class b;
+    b = sqrt(a); ASSERT_ALWAYS(b == 5);
+  }
+  {
+    mpz_class a(125);
+    mpz_class b;
+    b = sqrt(a); ASSERT_ALWAYS(b == 11); // round toward zero
+  }
+
+  // sgn
+  {
+    mpz_class a(123);
+    int b = sgn(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpz_class a(0);
+    int b = sgn(a); ASSERT_ALWAYS(b == 0);
+  }
+  {
+    mpz_class a(-123);
+    int b = sgn(a); ASSERT_ALWAYS(b == -1);
+  }
+
+
+  // binary operators and functions
+
+  // operator+
+  {
+    mpz_class a(1), b(2);
+    mpz_class c;
+    c = a + b; ASSERT_ALWAYS(c == 3);
+  }
+  {
+    mpz_class a(3);
+    signed int b = 4;
+    mpz_class c;
+    c = a + b; ASSERT_ALWAYS(c == 7);
+  }
+  {
+    mpz_class a(5);
+    double b = 6.0;
+    mpz_class c;
+    c = b + a; ASSERT_ALWAYS(c == 11);
+  }
+
+  // operator-
+  {
+    mpz_class a(3), b(6);
+    mpz_class c;
+    c = a - b; ASSERT_ALWAYS(c == -3);
+  }
+
+  // operator*
+  {
+    mpz_class a(-2), b(4);
+    mpz_class c;
+    c = a * b; ASSERT_ALWAYS(c == -8);
+  }
+  {
+    mpz_class a(2);
+    long b = -4;
+    mpz_class c;
+    c = a * b; ASSERT_ALWAYS(c == -8);
+    c = b * a; ASSERT_ALWAYS(c == -8);
+  }
+  {
+    mpz_class a(-2);
+    unsigned long b = 4;
+    mpz_class c;
+    c = a * b; ASSERT_ALWAYS(c == -8);
+    c = b * a; ASSERT_ALWAYS(c == -8);
+  }
+
+  // operator/ and operator%
+  {
+    mpz_class a(12), b(4);
+    mpz_class c;
+    c = a / b; ASSERT_ALWAYS(c == 3);
+    c = a % b; ASSERT_ALWAYS(c == 0);
+  }
+  {
+    mpz_class a(7), b(5);
+    mpz_class c;
+    c = a / b; ASSERT_ALWAYS(c == 1);
+    c = a % b; ASSERT_ALWAYS(c == 2);
+  }
+  {
+    mpz_class a(-10);
+    signed int ai = -10;
+    mpz_class b(3);
+    signed int bi = 3;
+    mpz_class c;
+    c = a / b;  ASSERT_ALWAYS(c == -3);
+    c = a % b;  ASSERT_ALWAYS(c == -1);
+    c = a / bi; ASSERT_ALWAYS(c == -3);
+    c = a % bi; ASSERT_ALWAYS(c == -1);
+    c = ai / b; ASSERT_ALWAYS(c == -3);
+    c = ai % b; ASSERT_ALWAYS(c == -1);
+  }
+  {
+    mpz_class a(-10);
+    signed int ai = -10;
+    mpz_class b(-3);
+    signed int bi = -3;
+    mpz_class c;
+    c = a / b;  ASSERT_ALWAYS(c == 3);
+    c = a % b;  ASSERT_ALWAYS(c == -1);
+    c = a / bi; ASSERT_ALWAYS(c == 3);
+    c = a % bi; ASSERT_ALWAYS(c == -1);
+    c = ai / b; ASSERT_ALWAYS(c == 3);
+    c = ai % b; ASSERT_ALWAYS(c == -1);
+  }
+  {
+    mpz_class a (LONG_MIN);
+    signed long ai = LONG_MIN;
+    mpz_class b = - mpz_class (LONG_MIN);
+    mpz_class c;
+    c = a / b;  ASSERT_ALWAYS(c == -1);
+    c = a % b;  ASSERT_ALWAYS(c == 0);
+    c = ai / b; ASSERT_ALWAYS(c == -1);
+    c = ai % b; ASSERT_ALWAYS(c == 0);
+  }
+
+  // operator&
+  // operator|
+  // operator^
+
+  // operator<<
+  {
+    mpz_class a(3);
+    unsigned int b = 4;
+    mpz_class c;
+    c = a << b; ASSERT_ALWAYS(c == 48);
+  }
+
+  // operator>>
+  {
+    mpz_class a(127);
+    unsigned int b = 4;
+    mpz_class c;
+    c = a >> b; ASSERT_ALWAYS(c == 7);
+  }
+
+  // operator==
+  // operator!=
+  // operator<
+  // operator<=
+  // operator>
+  // operator>=
+
+  // cmp
+  {
+    mpz_class a(123), b(45);
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpz_class a(123);
+    unsigned long b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpz_class a(123);
+    long b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpz_class a(123);
+    double b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+
+
+  // ternary operators
+
+  // mpz_addmul
+  {
+    mpz_class a(1), b(2), c(3);
+    mpz_class d;
+    d = a + b * c; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3;
+    mpz_class d;
+    d = a + b * c; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(3);
+    unsigned int c = 2;
+    mpz_class d;
+    d = a + c * b; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3;
+    mpz_class d;
+    d = a + b * c; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(3);
+    signed int c = 2;
+    mpz_class d;
+    d = a + c * b; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(2);
+    double c = 3.0;
+    mpz_class d;
+    d = a + b * c; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(3);
+    double c = 2.0;
+    mpz_class d;
+    d = a + c * b; ASSERT_ALWAYS(d == 7);
+  }
+
+  {
+    mpz_class a(2), b(3), c(4);
+    mpz_class d;
+    d = a * b + c; ASSERT_ALWAYS(d == 10);
+  }
+  {
+    mpz_class a(2), b(4);
+    unsigned int c = 3;
+    mpz_class d;
+    d = a * c + b; ASSERT_ALWAYS(d == 10);
+  }
+  {
+    mpz_class a(3), b(4);
+    unsigned int c = 2;
+    mpz_class d;
+    d = c * a + b; ASSERT_ALWAYS(d == 10);
+  }
+  {
+    mpz_class a(2), b(4);
+    signed int c = 3;
+    mpz_class d;
+    d = a * c + b; ASSERT_ALWAYS(d == 10);
+  }
+  {
+    mpz_class a(3), b(4);
+    signed int c = 2;
+    mpz_class d;
+    d = c * a + b; ASSERT_ALWAYS(d == 10);
+  }
+  {
+    mpz_class a(2), b(4);
+    double c = 3.0;
+    mpz_class d;
+    d = a * c + b; ASSERT_ALWAYS(d == 10);
+  }
+  {
+    mpz_class a(3), b(4);
+    double c = 2.0;
+    mpz_class d;
+    d = c * a + b; ASSERT_ALWAYS(d == 10);
+  }
+
+  // mpz_submul
+  {
+    mpz_class a(1), b(2), c(3);
+    mpz_class d;
+    d = a - b * c; ASSERT_ALWAYS(d == -5);
+  }
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3;
+    mpz_class d;
+    d = a - b * c; ASSERT_ALWAYS(d == -5);
+  }
+  {
+    mpz_class a(1), b(3);
+    unsigned int c = 2;
+    mpz_class d;
+    d = a - c * b; ASSERT_ALWAYS(d == -5);
+  }
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3;
+    mpz_class d;
+    d = a - b * c; ASSERT_ALWAYS(d == -5);
+  }
+  {
+    mpz_class a(1), b(3);
+    signed int c = 2;
+    mpz_class d;
+    d = a - c * b; ASSERT_ALWAYS(d == -5);
+  }
+  {
+    mpz_class a(1), b(2);
+    double c = 3.0;
+    mpz_class d;
+    d = a - b * c; ASSERT_ALWAYS(d == -5);
+  }
+  {
+    mpz_class a(1), b(3);
+    double c = 2.0;
+    mpz_class d;
+    d = a - c * b; ASSERT_ALWAYS(d == -5);
+  }
+
+  {
+    mpz_class a(2), b(3), c(4);
+    mpz_class d;
+    d = a * b - c; ASSERT_ALWAYS(d == 2);
+  }
+  {
+    mpz_class a(2), b(4);
+    unsigned int c = 3;
+    mpz_class d;
+    d = a * c - b; ASSERT_ALWAYS(d == 2);
+  }
+  {
+    mpz_class a(3), b(4);
+    unsigned int c = 2;
+    mpz_class d;
+    d = c * a - b; ASSERT_ALWAYS(d == 2);
+  }
+  {
+    mpz_class a(2), b(4);
+    signed int c = 3;
+    mpz_class d;
+    d = a * c - b; ASSERT_ALWAYS(d == 2);
+  }
+  {
+    mpz_class a(3), b(4);
+    signed int c = 2;
+    mpz_class d;
+    d = c * a - b; ASSERT_ALWAYS(d == 2);
+  }
+  {
+    mpz_class a(2), b(4);
+    double c = 3.0;
+    mpz_class d;
+    d = a * c - b; ASSERT_ALWAYS(d == 2);
+  }
+  {
+    mpz_class a(3), b(4);
+    double c = 2.0;
+    mpz_class d;
+    d = c * a - b; ASSERT_ALWAYS(d == 2);
+  }
+}
+
+void
+check_mpq (void)
+{
+  // unary operators and functions
+
+  // operator+
+  {
+    mpq_class a(1, 2);
+    mpq_class b;
+    b = +a; ASSERT_ALWAYS(b == 0.5);
+  }
+
+  // operator-
+  {
+    mpq_class a(3, 4);
+    mpq_class b;
+    b = -a; ASSERT_ALWAYS(b == -0.75);
+  }
+
+  // abs
+  {
+    mpq_class a(-123);
+    mpq_class b;
+    b = abs(a); ASSERT_ALWAYS(b == 123);
+  }
+
+  // sgn
+  {
+    mpq_class a(123);
+    int b = sgn(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpq_class a(0);
+    int b = sgn(a); ASSERT_ALWAYS(b == 0);
+  }
+  {
+    mpq_class a(-123);
+    int b = sgn(a); ASSERT_ALWAYS(b == -1);
+  }
+
+
+  // binary operators and functions
+
+  // operator+
+  {
+    mpq_class a(1, 2), b(3, 4);
+    mpq_class c;
+    c = a + b; ASSERT_ALWAYS(c == 1.25);
+  }
+  {
+    mpq_class a(1, 2);
+    signed int b = 2;
+    mpq_class c;
+    c = a + b; ASSERT_ALWAYS(c == 2.5);
+  }
+  {
+    mpq_class a(1, 2);
+    double b = 1.5;
+    mpq_class c;
+    c = b + a; ASSERT_ALWAYS(c == 2);
+  }
+
+  // operator-
+  {
+    mpq_class a(1, 2), b(3, 4);
+    mpq_class c;
+    c = a - b; ASSERT_ALWAYS(c == -0.25);
+  }
+
+  // operator*
+  {
+    mpq_class a(1, 3), b(3, 4);
+    mpq_class c;
+    c = a * b; ASSERT_ALWAYS(c == 0.25);
+    c = b * b; ASSERT_ALWAYS(c == 0.5625);
+  }
+
+  // operator/
+  {
+    mpq_class a(1, 2), b(2, 3);
+    mpq_class c;
+    c = a / b; ASSERT_ALWAYS(c == 0.75);
+  }
+  {
+    mpq_class one = 1;
+    mpq_class x(2, 5);
+    ASSERT_ALWAYS(1 / x == one / x);
+    ASSERT_ALWAYS(1u / x == one / x);
+    x = (-1) / x;
+    ASSERT_ALWAYS(x == -2.5);
+    ASSERT_ALWAYS(0 / x == 0);
+    ASSERT_ALWAYS(0u / x == 0);
+  }
+
+  // operator<<
+  // operator>>
+  // operator==
+  // operator!=
+  // operator<
+  // operator<=
+  // operator>
+  // operator>=
+
+  // cmp
+  {
+    mpq_class a(123), b(45);
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpq_class a(123);
+    unsigned long b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpq_class a(123);
+    long b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpq_class a(123);
+    double b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpq_class a(123);
+    mpz_class b(45);
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+}
+
+void
+check_mpf (void)
+{
+  // unary operators and functions
+
+  // operator+
+  {
+    mpf_class a(1);
+    mpf_class b;
+    b = +a; ASSERT_ALWAYS(b == 1);
+  }
+
+  // operator-
+  {
+    mpf_class a(2);
+    mpf_class b;
+    b = -a; ASSERT_ALWAYS(b == -2);
+  }
+
+  // abs
+  {
+    mpf_class a(-123);
+    mpf_class b;
+    b = abs(a); ASSERT_ALWAYS(b == 123);
+  }
+
+  // trunc
+  {
+    mpf_class a(1.5);
+    mpf_class b;
+    b = trunc(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpf_class a(-1.5);
+    mpf_class b;
+    b = trunc(a); ASSERT_ALWAYS(b == -1);
+  }
+
+  // floor
+  {
+    mpf_class a(1.9);
+    mpf_class b;
+    b = floor(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpf_class a(-1.1);
+    mpf_class b;
+    b = floor(a); ASSERT_ALWAYS(b == -2);
+  }
+
+  // ceil
+  {
+    mpf_class a(1.1);
+    mpf_class b;
+    b = ceil(a); ASSERT_ALWAYS(b == 2);
+  }
+  {
+    mpf_class a(-1.9);
+    mpf_class b;
+    b = ceil(a); ASSERT_ALWAYS(b == -1);
+  }
+
+  // sqrt
+  {
+    mpf_class a(25);
+    mpf_class b;
+    b = sqrt(a); ASSERT_ALWAYS(b == 5);
+  }
+  {
+    mpf_class a(2.25);
+    mpf_class b;
+    b = sqrt(a); ASSERT_ALWAYS(b == 1.5);
+  }
+
+  // sgn
+  {
+    mpf_class a(123);
+    int b = sgn(a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpf_class a(0);
+    int b = sgn(a); ASSERT_ALWAYS(b == 0);
+  }
+  {
+    mpf_class a(-123);
+    int b = sgn(a); ASSERT_ALWAYS(b == -1);
+  }
+
+
+  // binary operators and functions
+
+  // operator+
+  {
+    mpf_class a(1), b(2);
+    mpf_class c;
+    c = a + b; ASSERT_ALWAYS(c == 3);
+  }
+
+  // operator-
+  {
+    mpf_class a(3), b(4);
+    mpf_class c;
+    c = a - b; ASSERT_ALWAYS(c == -1);
+  }
+
+  // operator*
+  {
+    mpf_class a(2), b(5);
+    mpf_class c;
+    c = a * b; ASSERT_ALWAYS(c == 10);
+  }
+
+  // operator/
+  {
+    mpf_class a(7), b(4);
+    mpf_class c;
+    c = a / b; ASSERT_ALWAYS(c == 1.75);
+  }
+
+  // operator<<
+  // operator>>
+  // operator==
+  // operator!=
+  // operator<
+  // operator<=
+  // operator>
+  // operator>=
+
+  // hypot
+  {
+    mpf_class a(3), b(4);
+    mpf_class c;
+    c = hypot(a, b); ASSERT_ALWAYS(c == 5);
+  }
+
+  // cmp
+  {
+    mpf_class a(123), b(45);
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpf_class a(123);
+    unsigned long b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpf_class a(123);
+    long b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpf_class a(123);
+    double b = 45;
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpf_class a(123);
+    mpz_class b(45);
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+  {
+    mpf_class a(123);
+    mpq_class b(45);
+    int c;
+    c = cmp(a, b); ASSERT_ALWAYS(c > 0);
+    c = cmp(b, a); ASSERT_ALWAYS(c < 0);
+  }
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpz();
+  check_mpq();
+  check_mpf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-ops2.h b/third_party/gmp/tests/cxx/t-ops2.h
new file mode 100644
index 0000000..f8898ee
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ops2.h
@@ -0,0 +1,82 @@
+/* Test mp*_class operators and functions.
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <math.h>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+
+#define CHECK1(Type,a,fun) \
+  ASSERT_ALWAYS(fun((Type)(a))==fun(a))
+#define CHECK(Type1,Type2,a,b,op) \
+  ASSERT_ALWAYS(((Type1)(a) op (Type2)(b))==((a) op (b)))
+#define CHECK_G(Type,a,b,op) \
+  CHECK(Type,Type,a,b,op)
+#define CHECK_UI(Type,a,b,op) \
+  CHECK(Type,unsigned long,a,b,op); \
+  CHECK(unsigned long,Type,a,b,op)
+#define CHECK_SI(Type,a,b,op) \
+  CHECK(Type,long,a,b,op); \
+  CHECK(long,Type,a,b,op)
+#define CHECK_D(Type,a,b,op) \
+  CHECK(Type,double,a,b,op); \
+  CHECK(double,Type,a,b,op)
+#define CHECK_MPZ(Type,a,b,op) \
+  CHECK(Type,mpz_class,a,b,op); \
+  CHECK(mpz_class,Type,a,b,op)
+#define CHECK_MPQ(Type,a,b,op) \
+  CHECK(Type,mpq_class,a,b,op); \
+  CHECK(mpq_class,Type,a,b,op)
+#define CHECK_ALL_SIGNED(Type,a,b,op) \
+  CHECK_G(Type,a,b,op); \
+  CHECK_SI(Type,a,b,op); \
+  CHECK_D(Type,a,b,op)
+#define CHECK_ALL_SIGNS(Type,a,b,op) \
+  CHECK_ALL_SIGNED(Type,a,b,op); \
+  CHECK_ALL_SIGNED(Type,-(a),b,op); \
+  CHECK_ALL_SIGNED(Type,a,-(b),op); \
+  CHECK_ALL_SIGNED(Type,-(a),-(b),op)
+#define CHECK_ALL(Type,a,b,op) \
+  CHECK_ALL_SIGNED(Type,a,b,op); \
+  CHECK_UI(Type,a,b,op)
+#define CHECK_ALL_SIGNED_COMPARISONS(Type,a,b) \
+  CHECK_ALL_SIGNED(Type,a,b,<); \
+  CHECK_ALL_SIGNED(Type,a,b,>); \
+  CHECK_ALL_SIGNED(Type,a,b,<=); \
+  CHECK_ALL_SIGNED(Type,a,b,>=); \
+  CHECK_ALL_SIGNED(Type,a,b,==); \
+  CHECK_ALL_SIGNED(Type,a,b,!=)
+#define CHECK_ALL_SIGNS_COMPARISONS(Type,a,b) \
+  CHECK_ALL_SIGNS(Type,a,b,<); \
+  CHECK_ALL_SIGNS(Type,a,b,>); \
+  CHECK_ALL_SIGNS(Type,a,b,<=); \
+  CHECK_ALL_SIGNS(Type,a,b,>=); \
+  CHECK_ALL_SIGNS(Type,a,b,==); \
+  CHECK_ALL_SIGNS(Type,a,b,!=)
+#define CHECK_ALL_COMPARISONS(Type,a,b) \
+  CHECK_ALL(Type,a,b,<); \
+  CHECK_ALL(Type,a,b,>); \
+  CHECK_ALL(Type,a,b,<=); \
+  CHECK_ALL(Type,a,b,>=); \
+  CHECK_ALL(Type,a,b,==); \
+  CHECK_ALL(Type,a,b,!=)
diff --git a/third_party/gmp/tests/cxx/t-ops2f.cc b/third_party/gmp/tests/cxx/t-ops2f.cc
new file mode 100644
index 0000000..71c9e10
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ops2f.cc
@@ -0,0 +1,87 @@
+/* Test mp*_class operators and functions.
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "t-ops2.h"
+
+void checkf (){
+  ASSERT_ALWAYS(sqrt(mpf_class(7))>2.64);
+  ASSERT_ALWAYS(sqrt(mpf_class(7))<2.65);
+  ASSERT_ALWAYS(sqrt(mpf_class(0))==0);
+  // TODO: add some consistency checks, as described in
+  // https://gmplib.org/list-archives/gmp-bugs/2013-February/002940.html
+  CHECK1(mpf_class,1.9,trunc);
+  CHECK1(mpf_class,1.9,floor);
+  CHECK1(mpf_class,1.9,ceil);
+  CHECK1(mpf_class,4.3,trunc);
+  CHECK1(mpf_class,4.3,floor);
+  CHECK1(mpf_class,4.3,ceil);
+  CHECK1(mpf_class,-7.1,trunc);
+  CHECK1(mpf_class,-7.1,floor);
+  CHECK1(mpf_class,-7.1,ceil);
+  CHECK1(mpf_class,-2.8,trunc);
+  CHECK1(mpf_class,-2.8,floor);
+  CHECK1(mpf_class,-2.8,ceil);
+  CHECK1(mpf_class,-1.5,trunc);
+  CHECK1(mpf_class,-1.5,floor);
+  CHECK1(mpf_class,-1.5,ceil);
+  CHECK1(mpf_class,2.5,trunc);
+  CHECK1(mpf_class,2.5,floor);
+  CHECK1(mpf_class,2.5,ceil);
+  ASSERT_ALWAYS(hypot(mpf_class(-3),mpf_class(4))>4.9);
+  ASSERT_ALWAYS(hypot(mpf_class(-3),mpf_class(4))<5.1);
+  ASSERT_ALWAYS(hypot(mpf_class(-3),4.)>4.9);
+  ASSERT_ALWAYS(hypot(-3.,mpf_class(4))<5.1);
+  ASSERT_ALWAYS(hypot(mpf_class(-3),4l)>4.9);
+  ASSERT_ALWAYS(hypot(-3l,mpf_class(4))<5.1);
+  ASSERT_ALWAYS(hypot(mpf_class(-3),4ul)>4.9);
+  ASSERT_ALWAYS(hypot(3ul,mpf_class(4))<5.1);
+  CHECK(mpf_class,mpq_class,1.5,2.25,+);
+  CHECK(mpf_class,mpq_class,1.5,2.25,-);
+  CHECK(mpf_class,mpq_class,1.5,-2.25,*);
+  CHECK(mpf_class,mpq_class,1.5,-2,/);
+  CHECK_MPQ(mpf_class,-5.5,-2.25,+);
+  CHECK_MPQ(mpf_class,-5.5,-2.25,-);
+  CHECK_MPQ(mpf_class,-5.5,-2.25,*);
+  CHECK_MPQ(mpf_class,-5.25,-0.5,/);
+  CHECK_MPQ(mpf_class,5,-2,<);
+  CHECK_MPQ(mpf_class,5,-2,>);
+  CHECK_MPQ(mpf_class,5,-2,<=);
+  CHECK_MPQ(mpf_class,5,-2,>=);
+  CHECK_MPQ(mpf_class,5,-2,==);
+  CHECK_MPQ(mpf_class,5,-2,!=);
+  CHECK_MPQ(mpf_class,0,0,<);
+  CHECK_MPQ(mpf_class,0,0,>);
+  CHECK_MPQ(mpf_class,0,0,<=);
+  CHECK_MPQ(mpf_class,0,0,>=);
+  CHECK_MPQ(mpf_class,0,0,==);
+  CHECK_MPQ(mpf_class,0,0,!=);
+}
+
+int
+main (void)
+{
+  tests_start();
+
+  // Enough precision for 1 + denorm_min
+  mpf_set_default_prec(DBL_MANT_DIG-DBL_MIN_EXP+42);
+  checkf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-ops2qf.cc b/third_party/gmp/tests/cxx/t-ops2qf.cc
new file mode 100644
index 0000000..bd96f61
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ops2qf.cc
@@ -0,0 +1,89 @@
+/* Test mp*_class operators and functions.
+
+Copyright 2011, 2012, 2018 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "t-ops2.h"
+
+template<class T>
+void checkqf (){
+  CHECK_ALL(T,5.,0,+);
+  CHECK_ALL(T,5.,0,-);
+  CHECK_ALL(T,5.,2,+); CHECK_MPZ(T,5.,2,+);
+  CHECK_ALL(T,5.,2,-); CHECK_MPZ(T,5.,2,-);
+  CHECK_ALL(T,5.,2,*); CHECK_MPZ(T,5.,2,*);
+  CHECK_ALL(T,5.,2,/); CHECK_MPZ(T,5.,2,/);
+  CHECK_ALL(T,0.,2,/);
+  CHECK_ALL_SIGNS(T,11.,3,+);
+  CHECK_ALL_SIGNS(T,11.,3,-);
+  CHECK_ALL_SIGNS(T,13.,1,+);
+  CHECK_ALL_SIGNS(T,13.,1,-);
+  CHECK_ALL_SIGNS(T,11.,3,*);
+  CHECK_ALL_SIGNS(T,11.,4,/);
+  CHECK_SI(T,LONG_MIN,1,*);
+  CHECK_SI(T,0,3,*);
+  CHECK_ALL_COMPARISONS(T,5.,2);
+  CHECK_ALL_SIGNS_COMPARISONS(T,11.,3);
+  CHECK_MPZ(T,5,-2,<);
+  CHECK_MPZ(T,5,-2,>);
+  CHECK_MPZ(T,5,-2,<=);
+  CHECK_MPZ(T,5,-2,>=);
+  CHECK_MPZ(T,5,-2,==);
+  CHECK_MPZ(T,5,-2,!=);
+  CHECK_MPZ(T,0,0,<);
+  CHECK_MPZ(T,0,0,>);
+  CHECK_MPZ(T,0,0,<=);
+  CHECK_MPZ(T,0,0,>=);
+  CHECK_MPZ(T,0,0,==);
+  CHECK_MPZ(T,0,0,!=);
+  ASSERT_ALWAYS(T(6)<<2==6.*4);
+  ASSERT_ALWAYS(T(6)>>2==6./4);
+  ASSERT_ALWAYS(T(-13)<<2==-13.*4);
+  ASSERT_ALWAYS(T(-13)>>2==-13./4);
+  ASSERT_ALWAYS(++T(7)==8);
+  ASSERT_ALWAYS(++T(-8)==-7);
+  ASSERT_ALWAYS(--T(8)==7);
+  ASSERT_ALWAYS(--T(-7)==-8);
+  ASSERT_ALWAYS(+T(7)==7);
+  ASSERT_ALWAYS(+T(-8)==-8);
+  ASSERT_ALWAYS(-T(7)==-7);
+  ASSERT_ALWAYS(-T(-8)==8);
+  ASSERT_ALWAYS(abs(T(7))==7);
+  ASSERT_ALWAYS(abs(T(-8))==8);
+  ASSERT_ALWAYS(sgn(T(0))==0);
+  ASSERT_ALWAYS(sgn(T(9))==1);
+  ASSERT_ALWAYS(sgn(T(-17))==-1);
+  ASSERT_ALWAYS(T(1)+DBL_MAX>2);
+  ASSERT_ALWAYS(T(1)+DBL_MIN>1);
+  ASSERT_ALWAYS(T(1)+DBL_MIN<1.001);
+  ASSERT_ALWAYS(T(1)+std::numeric_limits<double>::denorm_min()>1);
+  ASSERT_ALWAYS(T(1)+std::numeric_limits<double>::denorm_min()<1.001);
+}
+
+int
+main (void)
+{
+  tests_start();
+
+  // Enough precision for 1 + denorm_min
+  mpf_set_default_prec(DBL_MANT_DIG-DBL_MIN_EXP+42);
+  checkqf<mpq_class>();
+  checkqf<mpf_class>();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-ops2z.cc b/third_party/gmp/tests/cxx/t-ops2z.cc
new file mode 100644
index 0000000..6d0e4ad
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ops2z.cc
@@ -0,0 +1,126 @@
+/* Test mp*_class operators and functions.
+
+Copyright 2011, 2012 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "t-ops2.h"
+
+void checkz (){
+  CHECK_ALL(mpz_class,5,2,+);
+  CHECK_ALL(mpz_class,5,2,-);
+  CHECK_ALL(mpz_class,5,2,*);
+  CHECK_ALL(mpz_class,5,2,/);
+  CHECK_ALL(mpz_class,5,2,%);
+  CHECK_ALL_COMPARISONS(mpz_class,5,2);
+  CHECK_ALL_SIGNS(mpz_class,11,3,+);
+  CHECK_ALL_SIGNS(mpz_class,11,3,-);
+  CHECK_ALL_SIGNS(mpz_class,11,3,*);
+  CHECK_ALL_SIGNS(mpz_class,11,3,/);
+  CHECK_ALL_SIGNS(mpz_class,11,3,%);
+  CHECK_ALL_SIGNS(mpz_class,17,2,*);
+  CHECK_ALL_SIGNS(mpz_class,17,2,/);
+  CHECK_ALL_SIGNS(mpz_class,17,2,%);
+  CHECK(unsigned long,mpz_class,5,-2,/);
+  CHECK(unsigned long,mpz_class,5,-2,%);
+  ASSERT_ALWAYS(7ul/mpz_class(1e35)==0);
+  ASSERT_ALWAYS(7ul%mpz_class(1e35)==7);
+  ASSERT_ALWAYS(7ul/mpz_class(-1e35)==0);
+  ASSERT_ALWAYS(7ul%mpz_class(-1e35)==7);
+  CHECK_ALL_SIGNS_COMPARISONS(mpz_class,11,3);
+  CHECK_ALL(mpz_class,6,3,&);
+  CHECK_ALL(mpz_class,6,3,|);
+  CHECK_ALL(mpz_class,6,3,^);
+  CHECK(mpz_class,unsigned long,6,2,<<);
+  CHECK(mpz_class,unsigned long,6,2,>>);
+  ASSERT_ALWAYS((mpz_class(-13)<<(unsigned long)2) == (-13)*4);
+  CHECK(mpz_class,unsigned long,-13,2,>>);
+  ASSERT_ALWAYS(++mpz_class(7)==8);
+  ASSERT_ALWAYS(++mpz_class(-8)==-7);
+  ASSERT_ALWAYS(--mpz_class(8)==7);
+  ASSERT_ALWAYS(--mpz_class(-7)==-8);
+  ASSERT_ALWAYS(~mpz_class(7)==-8);
+  ASSERT_ALWAYS(~mpz_class(-8)==7);
+  ASSERT_ALWAYS(+mpz_class(7)==7);
+  ASSERT_ALWAYS(+mpz_class(-8)==-8);
+  ASSERT_ALWAYS(-mpz_class(7)==-7);
+  ASSERT_ALWAYS(-mpz_class(-8)==8);
+  ASSERT_ALWAYS(abs(mpz_class(7))==7);
+  ASSERT_ALWAYS(abs(mpz_class(-8))==8);
+  ASSERT_ALWAYS(sqrt(mpz_class(7))==2);
+  ASSERT_ALWAYS(sqrt(mpz_class(0))==0);
+  ASSERT_ALWAYS(sgn(mpz_class(0))==0);
+  ASSERT_ALWAYS(sgn(mpz_class(9))==1);
+  ASSERT_ALWAYS(sgn(mpz_class(-17))==-1);
+  ASSERT_ALWAYS(mpz_class(1)+DBL_MAX>2);
+  ASSERT_ALWAYS(mpz_class(1)+DBL_MIN<2);
+  ASSERT_ALWAYS(mpz_class(1)+std::numeric_limits<double>::denorm_min()<2);
+  ASSERT_ALWAYS(gcd(mpz_class(6),mpz_class(8))==2);
+  ASSERT_ALWAYS(gcd(-mpz_class(6),mpz_class(8))==2);
+  ASSERT_ALWAYS(gcd(-mpz_class(6),-mpz_class(8))==2);
+  ASSERT_ALWAYS(gcd(mpz_class(6),8.f)==2);
+  ASSERT_ALWAYS(gcd(-mpz_class(6),static_cast<unsigned char>(8))==2);
+  ASSERT_ALWAYS(gcd(static_cast<long>(-6),mpz_class(5)+3)==2);
+  ASSERT_ALWAYS(lcm(mpz_class(6),mpz_class(8))==24);
+  ASSERT_ALWAYS(lcm(-mpz_class(6),mpz_class(8))==24);
+  ASSERT_ALWAYS(lcm(-mpz_class(6),-mpz_class(8))==24);
+  ASSERT_ALWAYS(lcm(mpz_class(6),static_cast<short>(8))==24);
+  ASSERT_ALWAYS(lcm(-mpz_class(6),static_cast<unsigned char>(8))==24);
+  ASSERT_ALWAYS(lcm(-6.,mpz_class(5)+3)==24);
+  ASSERT_ALWAYS(factorial(mpz_class(3))==6);
+  ASSERT_ALWAYS(factorial(mpz_class(5)-1)==24);
+  ASSERT_ALWAYS(mpz_class::factorial(mpz_class(3))==6);
+  ASSERT_ALWAYS(mpz_class::factorial(mpz_class(2)*2)==24);
+  ASSERT_ALWAYS(mpz_class::factorial(3)==6);
+  ASSERT_ALWAYS(mpz_class::factorial(3ul)==6);
+  ASSERT_ALWAYS(mpz_class::factorial(3.f)==6);
+  mpz_class ret;
+  try { ret=factorial(-mpz_class(3)); ASSERT_ALWAYS(0); }
+  catch (std::domain_error) {}
+  try { ret=mpz_class::factorial(-2); ASSERT_ALWAYS(0); }
+  catch (std::domain_error) {}
+  try { ret=factorial(mpz_class(1)<<300); ASSERT_ALWAYS(0); }
+  catch (std::bad_alloc) {}
+  ASSERT_ALWAYS(mpz_class::primorial(mpz_class(3))==6);
+  ASSERT_ALWAYS(mpz_class::primorial(mpz_class(2)*2)==6);
+  ASSERT_ALWAYS(mpz_class::primorial(3)==6);
+  ASSERT_ALWAYS(mpz_class::primorial(3ul)==6);
+  ASSERT_ALWAYS(mpz_class::primorial(3.f)==6);
+  try { ret=primorial(-mpz_class(3)); ASSERT_ALWAYS(0); }
+  catch (std::domain_error) {}
+  try { ret=mpz_class::primorial(-5); ASSERT_ALWAYS(0); }
+  catch (std::domain_error) {}
+  try { ret=primorial(mpz_class(1)<<300); ASSERT_ALWAYS(0); }
+  catch (std::bad_alloc) {}
+  ASSERT_ALWAYS(mpz_class::fibonacci(mpz_class(6))==8);
+  ASSERT_ALWAYS(mpz_class::fibonacci(mpz_class(2)*2)==3);
+  ASSERT_ALWAYS(mpz_class::fibonacci(3)==2);
+  ASSERT_ALWAYS(mpz_class::fibonacci(3ul)==2);
+  ASSERT_ALWAYS(mpz_class::fibonacci(3.f)==2);
+  ASSERT_ALWAYS(fibonacci(-mpz_class(6))==-8);
+  ASSERT_ALWAYS(mpz_class::fibonacci(-3)==2);
+  try { ret=fibonacci(mpz_class(1)<<300); ASSERT_ALWAYS(0); }
+  catch (std::bad_alloc) {}
+}
+
+int
+main (void)
+{
+  tests_start();
+  checkz();
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-ops3.cc b/third_party/gmp/tests/cxx/t-ops3.cc
new file mode 100644
index 0000000..baf49e1
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ops3.cc
@@ -0,0 +1,132 @@
+/* Test mp*_class assignment operators (+=, -=, etc)
+
+Copyright 2011 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+#define FOR_ALL_SIGNED_BUILTIN(F) \
+	F(signed char) \
+	F(signed short) \
+	F(signed int) \
+	F(signed long) \
+	F(float) \
+	F(double)
+
+#define FOR_ALL_BUILTIN(F) \
+	FOR_ALL_SIGNED_BUILTIN(F) \
+	F(char) \
+	F(unsigned char) \
+	F(unsigned short) \
+	F(unsigned int) \
+	F(unsigned long)
+
+#define FOR_ALL_GMPXX(F) \
+	F(mpz_class) \
+	F(mpq_class) \
+	F(mpf_class)
+
+template<class T,class U> void f(T t, U u){
+  T a=t;
+  ASSERT_ALWAYS((a+=u)==(t+u)); ASSERT_ALWAYS(a==(t+u));
+  ASSERT_ALWAYS((a-=u)==t); ASSERT_ALWAYS(a==t);
+  ASSERT_ALWAYS((a*=u)==(t*u)); ASSERT_ALWAYS(a==(t*u));
+  ASSERT_ALWAYS((a/=u)==t); ASSERT_ALWAYS(a==t);
+  ASSERT_ALWAYS((a<<=5)==(t<<5)); ASSERT_ALWAYS(a==(t<<5));
+  ASSERT_ALWAYS((a>>=5)==t); ASSERT_ALWAYS(a==t);
+}
+
+template<class T,class U> void g(T t, U u){
+  T a=t;
+  ASSERT_ALWAYS((a%=u)==(t%u)); ASSERT_ALWAYS(a==(t%u));
+  a=t;
+  ASSERT_ALWAYS((a&=u)==(t&u)); ASSERT_ALWAYS(a==(t&u));
+  a=t;
+  ASSERT_ALWAYS((a|=u)==(t|u)); ASSERT_ALWAYS(a==(t|u));
+  a=t;
+  ASSERT_ALWAYS((a^=u)==(t^u)); ASSERT_ALWAYS(a==(t^u));
+}
+
+template<class T> void h(T t){
+  T a=t;
+  ASSERT_ALWAYS((a<<=5)==(t<<5)); ASSERT_ALWAYS(a==(t<<5));
+  ASSERT_ALWAYS((a>>=5)==t); ASSERT_ALWAYS(a==t);
+}
+
+template<class T, class U> void ffs(T t, U u){
+#define F(V) f(t,(V)u);
+	FOR_ALL_SIGNED_BUILTIN(F)
+	FOR_ALL_GMPXX(F)
+#undef F
+#define F(V) f(t,-(V)u);
+	FOR_ALL_GMPXX(F)
+#undef F
+}
+
+template<class T, class U> void ff(T t, U u){
+#define F(V) f(t,(V)u);
+	FOR_ALL_BUILTIN(F)
+	FOR_ALL_GMPXX(F)
+#undef F
+#define F(V) f(t,-(V)u);
+	FOR_ALL_GMPXX(F)
+#undef F
+}
+
+template<class U> void ggs(mpz_class t, U u){
+#define F(V) g(t,(V)u);
+	FOR_ALL_SIGNED_BUILTIN(F)
+#undef F
+	g(t,(mpz_class)u);
+	g(t,-(mpz_class)u);
+}
+
+template<class U> void gg(mpz_class t, U u){
+#define F(V) g(t,(V)u);
+	FOR_ALL_BUILTIN(F)
+#undef F
+	g(t,(mpz_class)u);
+	g(t,-(mpz_class)u);
+}
+
+void check(){
+	mpz_class z=18;
+	mpq_class q(7,2);
+	mpf_class d=3.375;
+	h(z); h(q); h(d);
+	ff(z,13); ff(q,13); ff(d,13);
+	ffs(z,-42); ffs(q,-42); ffs(d,-42);
+	gg(z,33); ggs(z,-22);
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-ostream.cc b/third_party/gmp/tests/cxx/t-ostream.cc
new file mode 100644
index 0000000..8550f67
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ostream.cc
@@ -0,0 +1,449 @@
+/* Test ostream formatted output.
+
+Copyright 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include <iostream>
+#include <cstdlib>
+
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+bool option_check_standard = false;
+
+
+#define CALL(expr)							\
+  do {									\
+    got.flags (data[i].flags);						\
+    got.width (data[i].width);						\
+    got.precision (data[i].precision);					\
+    if (data[i].fill == '\0')						\
+      got.fill (' ');							\
+    else								\
+      got.fill (data[i].fill);						\
+									\
+    if (! (expr))							\
+      {									\
+	cout << "\"got\" output error\n";				\
+	abort ();							\
+      }									\
+    if (got.width() != 0)						\
+      {									\
+	cout << "\"got\" width not reset to 0\n";			\
+	abort ();							\
+      }									\
+									\
+  } while (0)
+
+
+#define DUMP()								\
+  do {									\
+    cout << "  want:  |" << data[i].want << "|\n";			\
+    cout << "  got:   |" << got.str() << "|\n";				\
+    cout << "  width: " << data[i].width << "\n";			\
+    cout << "  prec:  " << got.precision() << "\n";			\
+    cout << "  flags: " << hex << (unsigned long) got.flags() << "\n";	\
+  } while (0)
+
+#define ABORT() \
+  do {          \
+    DUMP ();    \
+    abort ();   \
+  } while (0)
+
+void
+check_mpz (void)
+{
+  static const struct {
+    const char     *z;
+    const char     *want;
+    ios::fmtflags  flags;
+    int            width;
+    int            precision;
+    char           fill;
+
+  } data[] = {
+
+    { "0", "0", ios::dec },
+
+    { "0", "0", ios::oct },
+    { "0", "0", ios::oct | ios::showbase },
+
+    { "0", "0", ios::hex },
+    { "0", "0x0", ios::hex | ios::showbase },
+    { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
+
+    { "1", "****1", ios::dec, 5, 0, '*' },
+
+    { "-1", "   -1",  ios::dec | ios::right,    5 },
+    { "-1", "-   1",  ios::dec | ios::internal, 5 },
+    { "-1", "-1   ",  ios::dec | ios::left,     5 },
+
+    { "1", "   0x1", ios::hex | ios::showbase | ios::right,    6 },
+    { "1", "0x   1", ios::hex | ios::showbase | ios::internal, 6 },
+    { "1", "0x1   ", ios::hex | ios::showbase | ios::left,     6 },
+
+    { "1", "   +0x1", ios::hex | ios::showbase | ios::showpos | ios::right,
+      7 },
+    { "1", "+0x   1", ios::hex | ios::showbase | ios::showpos | ios::internal,
+      7 },
+    { "1", "+0x1   ", ios::hex | ios::showbase | ios::showpos | ios::left,
+      7 },
+
+    {  "123",    "7b", ios::hex },
+    {  "123",    "7B", ios::hex | ios::uppercase },
+    {  "123",  "0x7b", ios::hex | ios::showbase },
+    {  "123",  "0X7B", ios::hex | ios::showbase | ios::uppercase },
+    { "-123", "-0x7b", ios::hex | ios::showbase },
+    { "-123", "-0X7B", ios::hex | ios::showbase | ios::uppercase },
+
+    {  "123",   "173", ios::oct },
+    {  "123",   "173", ios::oct | ios::uppercase },
+    {  "123",  "0173", ios::oct | ios::showbase },
+    {  "123",  "0173", ios::oct | ios::showbase | ios::uppercase },
+    { "-123", "-0173", ios::oct | ios::showbase },
+    { "-123", "-0173", ios::oct | ios::showbase | ios::uppercase },
+
+  };
+
+  size_t  i;
+  mpz_t   z;
+
+  mpz_init (z);
+
+  for (i = 0; i < numberof (data); i++)
+    {
+      mpz_set_str_or_abort (z, data[i].z, 0);
+
+      if (option_check_standard
+	  && mpz_fits_slong_p (z)
+
+	  // no negatives or showpos in hex or oct
+	  && (((data[i].flags & ios::basefield) == ios::hex
+	       || (data[i].flags & ios::basefield) == ios::oct)
+	      ? (mpz_sgn (z) >= 0
+		 && ! (data[i].flags & ios::showpos))
+	      : 1)
+	  )
+	{
+	  ostringstream  got;
+	  long  n = mpz_get_si (z);
+	  CALL (got << n);
+	  if (got.str().compare (data[i].want) != 0)
+	    {
+	      cout << "check_mpz data[" << i
+		   << "] doesn't match standard ostream output\n";
+	      cout << "  z:     " << data[i].z << "\n";
+	      cout << "  n:     " << n << "\n";
+	      DUMP ();
+	    }
+	}
+
+      {
+	ostringstream  got;
+	CALL (got << z);
+	if (got.str().compare (data[i].want) != 0)
+	  {
+	    cout << "mpz operator<< wrong, data[" << i << "]\n";
+	    cout << "  z:     " << data[i].z << "\n";
+	    ABORT ();
+	  }
+      }
+    }
+
+  mpz_clear (z);
+}
+
+void
+check_mpq (void)
+{
+  static const struct {
+    const char     *q;
+    const char     *want;
+    ios::fmtflags  flags;
+    int            width;
+    int            precision;
+    char           fill;
+
+  } data[] = {
+
+    { "0", "0", ios::dec },
+    { "0", "0", ios::hex },
+    { "0", "0x0", ios::hex | ios::showbase },
+    { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
+
+    { "5/8", "5/8", ios::dec },
+    { "5/8", "0X5/0X8", ios::hex | ios::showbase | ios::uppercase },
+
+    // zero denominator with showbase
+    { "0/0",   "       0/0", ios::oct | ios::showbase, 10 },
+    { "0/0",   "       0/0", ios::dec | ios::showbase, 10 },
+    { "0/0",   "   0x0/0x0", ios::hex | ios::showbase, 10 },
+    { "123/0", "    0173/0", ios::oct | ios::showbase, 10 },
+    { "123/0", "     123/0", ios::dec | ios::showbase, 10 },
+    { "123/0", "  0x7b/0x0", ios::hex | ios::showbase, 10 },
+    { "123/0", "  0X7B/0X0", ios::hex | ios::showbase | ios::uppercase, 10 },
+    { "0/123", "    0/0173", ios::oct | ios::showbase, 10 },
+    { "0/123", "     0/123", ios::dec | ios::showbase, 10 },
+    { "0/123", "  0x0/0x7b", ios::hex | ios::showbase, 10 },
+    { "0/123", "  0X0/0X7B", ios::hex | ios::showbase | ios::uppercase, 10 },
+  };
+
+  size_t  i;
+  mpq_t   q;
+
+  mpq_init (q);
+
+#define mpq_integer_p(q)  (mpz_cmp_ui (mpq_denref(q), 1L) == 0)
+
+  for (i = 0; i < numberof (data); i++)
+    {
+      mpq_set_str_or_abort (q, data[i].q, 0);
+      MPZ_CHECK_FORMAT (mpq_numref (q));
+      MPZ_CHECK_FORMAT (mpq_denref (q));
+
+      if (option_check_standard
+	  && mpz_fits_slong_p (mpq_numref(q))
+	  && mpq_integer_p (q))
+	{
+	  ostringstream  got;
+	  long  n = mpz_get_si (mpq_numref(q));
+	  CALL (got << n);
+	  if (got.str().compare (data[i].want) != 0)
+	    {
+	      cout << "check_mpq data[" << i
+		   << "] doesn't match standard ostream output\n";
+	      cout << "  q:     " << data[i].q << "\n";
+	      cout << "  n:     " << n << "\n";
+	      DUMP ();
+	    }
+	}
+
+      {
+	ostringstream  got;
+	CALL (got << q);
+	if (got.str().compare (data[i].want) != 0)
+	  {
+	    cout << "mpq operator<< wrong, data[" << i << "]\n";
+	    cout << "  q:     " << data[i].q << "\n";
+	    ABORT ();
+	  }
+      }
+    }
+
+  mpq_clear (q);
+}
+
+
+void
+check_mpf (void)
+{
+  static const struct {
+    const char     *f;
+    const char     *want;
+    ios::fmtflags  flags;
+    int            width;
+    int            precision;
+    char           fill;
+
+  } data[] = {
+
+    { "0", "0",            ios::dec },
+    { "0", "+0",           ios::dec | ios::showpos },
+    { "0", "0.00000",      ios::dec | ios::showpoint },
+    { "0", "0",            ios::dec | ios::fixed },
+    { "0", "0.",           ios::dec | ios::fixed | ios::showpoint },
+    { "0", "0.000000e+00", ios::dec | ios::scientific },
+    { "0", "0.000000e+00", ios::dec | ios::scientific | ios::showpoint },
+
+    { "0", "0",          ios::dec, 0, 4 },
+    { "0", "0.000",      ios::dec | ios::showpoint, 0, 4 },
+    { "0", "0.0000",     ios::dec | ios::fixed, 0, 4 },
+    { "0", "0.0000",     ios::dec | ios::fixed | ios::showpoint, 0, 4 },
+    { "0", "0.0000e+00", ios::dec | ios::scientific, 0, 4 },
+    { "0", "0.0000e+00", ios::dec | ios::scientific | ios::showpoint, 0, 4 },
+
+    { "1", "1",       ios::dec },
+    { "1", "+1",      ios::dec | ios::showpos },
+    { "1", "1.00000", ios::dec | ios::showpoint },
+    { "1", "1",       ios::dec | ios::fixed },
+    { "1", "1.",      ios::dec | ios::fixed | ios::showpoint },
+    { "1", "1.000000e+00",   ios::dec | ios::scientific },
+    { "1", "1.000000e+00",  ios::dec | ios::scientific | ios::showpoint },
+
+    { "1", "1",          ios::dec,                   0, 4 },
+    { "1", "1.000",      ios::dec | ios::showpoint,  0, 4 },
+    { "1", "1.0000",     ios::dec | ios::fixed,      0, 4 },
+    { "1", "1.0000",     ios::dec | ios::fixed | ios::showpoint, 0, 4 },
+    { "1", "1.0000e+00", ios::dec | ios::scientific, 0, 4 },
+    { "1", "1.0000e+00", ios::dec | ios::scientific | ios::showpoint, 0, 4 },
+
+    { "-1", "-1",        ios::dec | ios::showpos },
+
+    { "-1", "  -1",      ios::dec, 4 },
+    { "-1", "-  1",      ios::dec | ios::internal, 4 },
+    { "-1", "-1  ",      ios::dec | ios::left, 4 },
+
+    { "-1", "  -0x1",    ios::hex | ios::showbase, 6 },
+    { "-1", "-0x  1",    ios::hex | ios::showbase | ios::internal, 6 },
+    { "-1", "-0x1  ",    ios::hex | ios::showbase | ios::left, 6 },
+
+    {    "1", "*********1", ios::dec, 10, 4, '*' },
+    { "1234", "******1234", ios::dec, 10, 4, '*' },
+    { "1234", "*****1234.", ios::dec | ios::showpoint, 10, 4, '*' },
+
+    { "12345", "1.23e+04", ios::dec, 0, 3 },
+
+    { "12345", "12345.", ios::dec | ios::fixed | ios::showpoint },
+
+    { "1.9999999",    "2",     ios::dec, 0, 1 },
+    { "1.0009999999", "1.001", ios::dec, 0, 4 },
+    { "1.0001",       "1",     ios::dec, 0, 4 },
+    { "1.0004",       "1",     ios::dec, 0, 4 },
+    { "1.000555",     "1.001", ios::dec, 0, 4 },
+
+    { "1.0002",       "1.000", ios::dec | ios::fixed, 0, 3 },
+    { "1.0008",       "1.001", ios::dec | ios::fixed, 0, 3 },
+
+    { "0", "0", ios::hex },
+    { "0", "0x0", ios::hex | ios::showbase },
+    { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
+    { "123",   "7b", ios::hex },
+    { "123", "0x7b", ios::hex | ios::showbase },
+    { "123", "0X7B", ios::hex | ios::showbase | ios::uppercase },
+
+    { "0", "0.000@+00", ios::hex | ios::scientific, 0, 3 },
+    { "256", "1.000@+02", ios::hex | ios::scientific, 0, 3 },
+
+    { "123",   "7.b@+01", ios::hex | ios::scientific, 0, 1 },
+    { "123",   "7.B@+01", ios::hex | ios::scientific | ios::uppercase, 0, 1 },
+    { "123", "0x7.b@+01", ios::hex | ios::scientific | ios::showbase, 0, 1 },
+    { "123", "0X7.B@+01",
+      ios::hex | ios::scientific | ios::showbase | ios::uppercase, 0, 1 },
+
+    { "1099511627776", "1.0@+10", ios::hex | ios::scientific, 0, 1 },
+    { "1099511627776", "1.0@+10",
+      ios::hex | ios::scientific | ios::uppercase, 0, 1 },
+
+    { "0.0625", "1.00@-01", ios::hex | ios::scientific, 0, 2 },
+
+    { "0", "0", ios::oct },
+    { "123",  "173", ios::oct },
+    { "123", "0173", ios::oct | ios::showbase },
+
+    // octal showbase suppressed for 0
+    { "0", "0", ios::oct | ios::showbase },
+    { ".125",    "00.1",  ios::oct | ios::showbase, 0, 1 },
+    { ".015625", "00.01", ios::oct | ios::showbase, 0, 2 },
+    { ".125",    "00.1",  ios::fixed | ios::oct | ios::showbase, 0, 1 },
+    { ".015625", "0.0",   ios::fixed | ios::oct | ios::showbase, 0, 1 },
+    { ".015625", "00.01", ios::fixed | ios::oct | ios::showbase, 0, 2 },
+
+    {  "0.125",  "1.000000e-01", ios::oct | ios::scientific },
+    {  "0.125", "+1.000000e-01", ios::oct | ios::scientific | ios::showpos },
+    { "-0.125", "-1.000000e-01", ios::oct | ios::scientific },
+    { "-0.125", "-1.000000e-01", ios::oct | ios::scientific | ios::showpos },
+
+    { "0", "0.000e+00", ios::oct | ios::scientific, 0, 3 },
+    { "256",  "4.000e+02", ios::oct | ios::scientific, 0, 3 },
+    { "256", "04.000e+02", ios::oct | ios::scientific | ios::showbase, 0, 3 },
+    { "256",  "4.000E+02", ios::oct | ios::scientific | ios::uppercase, 0, 3 },
+    { "256", "04.000E+02",
+      ios::oct | ios::scientific | ios::showbase | ios::uppercase, 0, 3 },
+
+    { "16777216",    "1.000000e+08", ios::oct | ios::scientific },
+    { "16777216",    "1.000000E+08",
+      ios::oct | ios::scientific | ios::uppercase },
+    { "16777216",   "01.000000e+08",
+      ios::oct | ios::scientific | ios::showbase },
+    { "16777216",   "01.000000E+08",
+      ios::oct | ios::scientific | ios::showbase | ios::uppercase },
+    { "16777216",  "+01.000000e+08",
+      ios::oct | ios::scientific | ios::showbase | ios::showpos },
+    { "16777216",  "+01.000000E+08", ios::oct | ios::scientific
+      | ios::showbase | ios::showpos | ios::uppercase },
+    { "-16777216", "-01.000000e+08",
+      ios::oct | ios::scientific | ios::showbase | ios::showpos },
+    { "-16777216", "-01.000000E+08", ios::oct | ios::scientific
+      | ios::showbase | ios::showpos | ios::uppercase },
+
+  };
+
+  size_t  i;
+  mpf_t   f, f2;
+  double  d;
+
+  mpf_init (f);
+  mpf_init (f2);
+
+  for (i = 0; i < numberof (data); i++)
+    {
+      mpf_set_str_or_abort (f, data[i].f, 0);
+
+      d = mpf_get_d (f);
+      mpf_set_d (f2, d);
+      if (option_check_standard && mpf_cmp (f, f2) == 0
+	  && ! (data[i].flags & (ios::hex | ios::oct | ios::showbase)))
+	{
+	  ostringstream  got;
+	  CALL (got << d);
+	  if (got.str().compare (data[i].want) != 0)
+	    {
+	      cout << "check_mpf data[" << i
+		   << "] doesn't match standard ostream output\n";
+	      cout << "  f:     " << data[i].f << "\n";
+	      cout << "  d:     " << d << "\n";
+	      DUMP ();
+	    }
+	}
+
+      {
+	ostringstream  got;
+	CALL (got << f);
+	if (got.str().compare (data[i].want) != 0)
+	  {
+	    cout << "mpf operator<< wrong, data[" << i << "]\n";
+	    cout << "  f:     " << data[i].f << "\n";
+	    ABORT ();
+	  }
+      }
+    }
+
+  mpf_clear (f);
+  mpf_clear (f2);
+}
+
+
+
+int
+main (int argc, char *argv[])
+{
+  if (argc > 1 && strcmp (argv[1], "-s") == 0)
+    option_check_standard = true;
+
+  tests_start ();
+
+  check_mpz ();
+  check_mpq ();
+  check_mpf ();
+
+  tests_end ();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-prec.cc b/third_party/gmp/tests/cxx/t-prec.cc
new file mode 100644
index 0000000..72fca72
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-prec.cc
@@ -0,0 +1,216 @@
+/* Test precision of mpf_class expressions.
+
+Copyright 2001-2003, 2008 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <iostream>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+const int
+small_prec = 64, medium_prec = 128, large_prec = 192, very_large_prec = 256;
+
+#define ASSERT_ALWAYS_PREC(a, s, prec) \
+{                                      \
+  mpf_srcptr _a = a.get_mpf_t();       \
+  mpf_class _b(s, prec);               \
+  mpf_srcptr _c = _b.get_mpf_t();      \
+  ASSERT_ALWAYS(mpf_eq(_a, _c, prec)); \
+}
+
+
+
+void
+check_mpf (void)
+{
+  mpf_set_default_prec(medium_prec);
+
+  // simple expressions
+  {
+    mpf_class f(3.0, small_prec);
+    mpf_class g(1 / f, very_large_prec);
+    ASSERT_ALWAYS_PREC
+      (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
+       "     33333 33333 33333 33333 33333 333", very_large_prec);
+  }
+  {
+    mpf_class f(9.0, medium_prec);
+    mpf_class g(0.0, very_large_prec);
+    g = 1 / f;
+    ASSERT_ALWAYS_PREC
+      (g, "0.11111 11111 11111 11111 11111 11111 11111 11111 11111 11111"
+       "     11111 11111 11111 11111 11111 111", very_large_prec);
+  }
+  {
+    mpf_class f(15.0, large_prec);
+    mpf_class g(0.0, very_large_prec);
+    g = 1 / f;
+    ASSERT_ALWAYS_PREC
+      (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
+       "     66666 66666 66666 66666 66666 667", very_large_prec);
+  }
+
+  // compound expressions
+  {
+    mpf_class f(3.0, small_prec);
+    mpf_class g(-(-(-1 / f)), very_large_prec);
+    ASSERT_ALWAYS_PREC
+      (g, "-0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
+       "      33333 33333 33333 33333 33333 333", very_large_prec);
+  }
+  {
+    mpf_class f(3.0, small_prec), g(9.0, medium_prec);
+    mpf_class h(0.0, very_large_prec);
+    h = 1/f + 1/g;
+    ASSERT_ALWAYS_PREC
+      (h, "0.44444 44444 44444 44444 44444 44444 44444 44444 44444 44444"
+       "     44444 44444 44444 44444 44444 444", very_large_prec);
+  }
+  {
+    mpf_class f(3.0, small_prec), g(9.0, medium_prec), h(15.0, large_prec);
+    mpf_class i(0.0, very_large_prec);
+    i = f / g + h;
+    ASSERT_ALWAYS_PREC
+      (i, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
+       "      33333 33333 33333 33333 33333 3", very_large_prec);
+  }
+  {
+    mpf_class f(3.0, small_prec);
+    mpf_class g(-(1 + f) / 3, very_large_prec);
+    ASSERT_ALWAYS_PREC
+      (g, "-1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
+       "      33333 33333 33333 33333 33333 33", very_large_prec);
+  }
+  {
+    mpf_class f(9.0, medium_prec);
+    mpf_class g(0.0, very_large_prec);
+    g = sqrt(1 / f);
+    ASSERT_ALWAYS_PREC
+      (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
+       "     33333 33333 33333 33333 33333 333", very_large_prec);
+  }
+  {
+    mpf_class f(15.0, large_prec);
+    mpf_class g(0.0, very_large_prec);
+    g = hypot(1 + 5 / f, 1.0);
+    ASSERT_ALWAYS_PREC
+      (g, "1.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
+       "     66666 66666 66666 66666 66666 67", very_large_prec);
+  }
+
+  // compound assignments
+  {
+    mpf_class f(3.0, small_prec), g(9.0, medium_prec);
+    mpf_class h(1.0, very_large_prec);
+    h -= f / g;
+    ASSERT_ALWAYS_PREC
+      (h, "0.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
+       "     66666 66666 66666 66666 66666 667", very_large_prec);
+  }
+
+  // construction from expressions
+  {
+    mpf_class f(3.0, small_prec);
+    mpf_class g(0.0, very_large_prec);
+    g = mpf_class(1 / f);
+    ASSERT_ALWAYS_PREC(g, "0.33333 33333 33333 33333", small_prec);
+  }
+  {
+    mpf_class f(9.0, medium_prec);
+    mpf_class g(0.0, very_large_prec);
+    g = mpf_class(1 / f);
+    ASSERT_ALWAYS_PREC
+      (g, "0.11111 11111 11111 11111 11111 11111 11111 1111", medium_prec);
+  }
+  {
+    mpf_class f(15.0, large_prec);
+    mpf_class g(0.0, very_large_prec);
+    g = mpf_class(1 / f);
+    ASSERT_ALWAYS_PREC
+      (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
+       "     66666 6667", large_prec);
+  }
+
+  {
+    mpf_class f(3.0, small_prec), g(9.0, medium_prec);
+    mpf_class h(0.0, very_large_prec);
+    h = mpf_class(f / g + 1, large_prec);
+    ASSERT_ALWAYS_PREC
+      (h, "1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
+       "     33333 333",
+       large_prec);
+  }
+
+  // mixed mpf/mpq expressions
+  {
+    mpf_class f(3.0, small_prec);
+    mpq_class q(1, 3);
+    mpf_class g(0.0, very_large_prec);
+    g = f - q;
+    ASSERT_ALWAYS_PREC
+      (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
+       "     66666 66666 66666 66666 66666 67", very_large_prec);
+  }
+
+  {
+    mpf_class f(3.0, small_prec);
+    mpq_class q(1, 3);
+    mpf_class g(0.0, very_large_prec);
+    g = mpf_class(f - q, large_prec);
+    ASSERT_ALWAYS_PREC
+      (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666"
+       "     66666 667",
+       large_prec);
+  }
+  {
+    mpf_class f(3.0, small_prec);
+    mpq_class q(1, 3);
+    mpf_class g(0.0, very_large_prec);
+    g = mpf_class(f - q);
+    ASSERT_ALWAYS_PREC
+      (g, "2.66666 66666 66666 66666 66666 66666 66666 667", medium_prec);
+  }
+  {
+    mpf_class f(15.0, large_prec);
+    mpq_class q(1, 3);
+    mpf_class g(0.0, very_large_prec);
+    g = mpf_class(f + q);
+    ASSERT_ALWAYS_PREC
+      (g, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333"
+       "      33333 33",
+       large_prec);
+  }
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-rand.cc b/third_party/gmp/tests/cxx/t-rand.cc
new file mode 100644
index 0000000..1f011eb
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-rand.cc
@@ -0,0 +1,148 @@
+/* Test gmp_randclass.
+
+Copyright 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+/* all flavours of initialization */
+void
+check_randinit (void)
+{
+  {
+    gmp_randclass r(gmp_randinit_default);
+  }
+
+  {
+    mpz_class a(0);
+    unsigned long c = 0, m2exp = 8;
+    gmp_randclass r(gmp_randinit_lc_2exp, a, c, m2exp);
+  }
+
+  {
+    unsigned long m2exp = 64;
+    gmp_randclass r(gmp_randinit_lc_2exp_size, m2exp);
+  }
+
+  /* gmp_randinit_lc_2exp_size, with excessive size */
+  {
+    try {
+      unsigned long m2exp = ULONG_MAX;
+      gmp_randclass r(gmp_randinit_lc_2exp_size, m2exp);
+      ASSERT_ALWAYS (0);  /* should not be reached */
+    } catch (length_error) {
+    }
+  }
+
+  {
+    gmp_randclass r(gmp_randinit_mt);
+  }
+
+  /* obsolete, but still available */
+  {
+    gmp_randalg_t alg = GMP_RAND_ALG_LC;
+    unsigned long m2exp = 64;
+    gmp_randclass r(alg, m2exp);
+  }
+  {
+    gmp_randalg_t alg = GMP_RAND_ALG_DEFAULT;
+    unsigned long m2exp = 64;
+    gmp_randclass r(alg, m2exp);
+  }
+  {
+    gmp_randalg_t alg = (gmp_randalg_t) 0;
+    unsigned long m2exp = 64;
+    gmp_randclass r(alg, m2exp);
+  }
+}
+
+void
+check_mpz (void)
+{
+  {
+    gmp_randclass r(gmp_randinit_default);
+    mpz_class a(123);
+    unsigned int b = 256;
+    mpz_class c;
+    r.seed(a);
+    c = r.get_z_bits(b);
+  }
+  {
+    gmp_randclass r(gmp_randinit_default);
+    mpz_class a(256);
+    unsigned long b = 123;
+    mpz_class c;
+    r.seed(b);
+    c = r.get_z_bits(a);
+  }
+  {
+    gmp_randclass r(gmp_randinit_default);
+    mpz_class a(123), b(256);
+    mpz_class c;
+    r.seed(a);
+    c = r.get_z_range(b);
+  }
+}
+
+void
+check_mpf (void)
+{
+  {
+    gmp_randclass r(gmp_randinit_default);
+    mpz_class a(123);
+    r.seed(a);
+    mpf_class b;
+    b = r.get_f();
+    mpf_class c(r.get_f());
+    ASSERT_ALWAYS (c.get_prec() == mpf_get_default_prec());
+    mpf_class d(r.get_f(),212);
+    ASSERT_ALWAYS (d.get_prec() >= 212);
+  }
+  {
+    gmp_randclass r(gmp_randinit_default);
+    int a = 123, b = 198;
+    r.seed(a);
+    mpf_class c;
+    c = r.get_f(b);
+    ASSERT_ALWAYS (c.get_prec() == mpf_get_default_prec());
+    mpf_class d(r.get_f(b));
+    ASSERT_ALWAYS (d.get_prec() >= 198);
+    mpf_class e(r.get_f(b)-r.get_f());
+    ASSERT_ALWAYS (e.get_prec() >= 198);
+    mpf_class f(r.get_f(60),300);
+    ASSERT_ALWAYS (f.get_prec() >= 300);
+  }
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_randinit();
+  check_mpz();
+  check_mpf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-ternary.cc b/third_party/gmp/tests/cxx/t-ternary.cc
new file mode 100644
index 0000000..8d087fb
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-ternary.cc
@@ -0,0 +1,734 @@
+/* Test mp*_class ternary expressions.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <iostream>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+/* The various test cases are broken up into separate functions to keep down
+   compiler memory use.  They're static so that any mistakenly omitted from
+   main() will provoke warnings (under gcc -Wall at least).  */
+
+static void
+check_mpz_1 (void)
+{
+  // template<class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<mpz_class, mpz_class, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    mpz_class d;
+    d = a + b * c; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    mpz_class d;
+    d = a - b * c; ASSERT_ALWAYS(d == -5);
+  }
+}
+
+static void
+check_mpz_2 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<mpz_class, T, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3;
+    mpz_class d;
+    d = a + b * c; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3;
+    mpz_class d;
+    d = a - b * c; ASSERT_ALWAYS(d == -5);
+  }
+}
+
+static void
+check_mpz_3 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<T, mpz_class, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3;
+    mpz_class d;
+    d = a + c * b; ASSERT_ALWAYS(d == 7);
+  }
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3;
+    mpz_class d;
+    d = a - c * b; ASSERT_ALWAYS(d == -5);
+  }
+}
+
+static void
+check_mpz_4 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpz_t, T>, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    double d = 4.0;
+    mpz_class e;
+    e = a + b * (c + d); ASSERT_ALWAYS(e == 15);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    double d = 4.0;
+    mpz_class e;
+    e = a - b * (c + d); ASSERT_ALWAYS(e == -13);
+  }
+}
+
+static void
+check_mpz_5 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpz_class, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    signed int d = 4;
+    mpz_class e;
+    e = a + (b - d) * c; ASSERT_ALWAYS(e == -5);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    signed int d = 4;
+    mpz_class e;
+    e = a - (b - d) * c; ASSERT_ALWAYS(e == 7);
+  }
+}
+
+static void
+check_mpz_6 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, U, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3, d = 4;
+    mpz_class e;
+    e = a + (b + c) * d; ASSERT_ALWAYS(e == 21);
+  }
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3, d = 4;
+    mpz_class e;
+    e = a - (b + c) * d; ASSERT_ALWAYS(e == -19);
+  }
+}
+
+static void
+check_mpz_7 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<T, __gmp_expr<mpz_t, U>, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    double c = 3.0, d = 4.0;
+    mpz_class e;
+    e = a + c * (b + d); ASSERT_ALWAYS(e == 19);
+  }
+  {
+    mpz_class a(1), b(2);
+    double c = 3.0, d = 4.0;
+    mpz_class e;
+    e = a - c * (b + d); ASSERT_ALWAYS(e == -17);
+  }
+}
+
+static void
+check_mpz_8 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, __gmp_expr<mpz_t, U>,
+  // Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    signed int d = 4, e = 5;
+    mpz_class f;
+    f = a + (b - d) * (c + e); ASSERT_ALWAYS(f == -15);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    signed int d = 4, e = 5;
+    mpz_class f;
+    f = a - (b - d) * (c + e); ASSERT_ALWAYS(f == 17);
+  }
+}
+
+static void
+check_mpz_9 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>,
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, mpz_class, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    unsigned int d = 4;
+    mpz_class e;
+    e = (a + d) + b * c; ASSERT_ALWAYS(e == 11);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    unsigned int d = 4;
+    mpz_class e;
+    e = (a + d) - b * c; ASSERT_ALWAYS(e == -1);
+  }
+}
+
+static void
+check_mpz_10 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>,
+  // __gmp_expr<mpz_t, __gmp_binary_expr<mpz_class, U, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    double c = 3.0, d = 4.0;
+    mpz_class e;
+    e = (a - c) + b * d; ASSERT_ALWAYS(e == 6);
+  }
+  {
+    mpz_class a(1), b(2);
+    double c = 3.0, d = 4.0;
+    mpz_class e;
+    e = (a - c) - b * d; ASSERT_ALWAYS(e == -10);
+  }
+}
+
+static void
+check_mpz_11 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>,
+  // __gmp_expr<mpz_t, __gmp_binary_expr<U, mpz_class, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3, d = 4;
+    mpz_class e;
+    e = (a - c) + d * b; ASSERT_ALWAYS(e == 6);
+  }
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3, d = 4;
+    mpz_class e;
+    e = (a - c) - d * b; ASSERT_ALWAYS(e == -10);
+  }
+}
+
+static void
+check_mpz_12 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpz_t, U>, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    unsigned int d = 4, e = 5;
+    mpz_class f;
+    f = (a + d) + b * (c - e); ASSERT_ALWAYS(f == 1);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    unsigned int d = 4, e = 5;
+    mpz_class f;
+    f = (a + d) - b * (c - e); ASSERT_ALWAYS(f == 9);
+  }
+}
+
+static void
+check_mpz_13 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, U>, mpz_class, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    double d = 4.0, e = 5.0;
+    mpz_class f;
+    f = (a - d) + (b + e) * c; ASSERT_ALWAYS(f == 18);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    double d = 4.0, e = 5.0;
+    mpz_class f;
+    f = (a - d) - (b + e) * c; ASSERT_ALWAYS(f == -24);
+  }
+
+}
+
+static void
+check_mpz_14 (void)
+{
+  // template <class T, class U, class V, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, U>, V, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3, d = 4, e = 5;
+    mpz_class f;
+    f = (a + c) + (b + d) * e; ASSERT_ALWAYS(f == 34);
+  }
+  {
+    mpz_class a(1), b(2);
+    signed int c = 3, d = 4, e = 5;
+    mpz_class f;
+    f = (a + c) - (b + d) * e; ASSERT_ALWAYS(f == -26);
+  }
+}
+
+static void
+check_mpz_15 (void)
+{
+  // template <class T, class U, class V, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<U, __gmp_expr<mpz_t, V>, Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3, d = 4, e = 5;
+    mpz_class f;
+    f = (a - c) + d * (b - e); ASSERT_ALWAYS(f == -14);
+  }
+  {
+    mpz_class a(1), b(2);
+    unsigned int c = 3, d = 4, e = 5;
+    mpz_class f;
+    f = (a - c) - d * (b - e); ASSERT_ALWAYS(f == 10);
+  }
+
+}
+
+static void
+check_mpz_16 (void)
+{
+  // template <class T, class U, class V, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, __gmp_expr
+  // <mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, U>, __gmp_expr<mpz_t, V>,
+  // Op1> >, Op2> >
+  {
+    mpz_class a(1), b(2), c(3);
+    double d = 4.0, e = 5.0, f = 6.0;
+    mpz_class g;
+    g = (a + d) + (b - e) * (c + f); ASSERT_ALWAYS(g == -22);
+  }
+  {
+    mpz_class a(1), b(2), c(3);
+    double d = 4.0, e = 5.0, f = 6.0;
+    mpz_class g;
+    g = (a + d) - (b - e) * (c + f); ASSERT_ALWAYS(g == 32);
+  }
+}
+
+static void
+check_mpz_17 (void)
+{
+  // template <class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr
+  // <mpz_t, __gmp_binary_expr<mpz_class, mpz_class, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    mpz_class d;
+    d = a * b + c; ASSERT_ALWAYS(d == 10);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    mpz_class d;
+    d = a * b - c; ASSERT_ALWAYS(d == 2);
+  }
+}
+
+static void
+check_mpz_18 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr
+  // <mpz_t, __gmp_binary_expr<mpz_class, T, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3);
+    signed int c = 4;
+    mpz_class d;
+    d = a * c + b; ASSERT_ALWAYS(d == 11);
+  }
+  {
+    mpz_class a(2), b(3);
+    signed int c = 4;
+    mpz_class d;
+    d = a * c - b; ASSERT_ALWAYS(d == 5);
+  }
+
+}
+
+static void
+check_mpz_19 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr
+  // <mpz_t, __gmp_binary_expr<T, mpz_class, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3);
+    unsigned int c = 4;
+    mpz_class d;
+    d = c * a + b; ASSERT_ALWAYS(d == 11);
+  }
+  {
+    mpz_class a(2), b(3);
+    unsigned int c = 4;
+    mpz_class d;
+    d = c * a - b; ASSERT_ALWAYS(d == 5);
+  }
+}
+
+static void
+check_mpz_20 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <mpz_class, __gmp_expr<mpz_t, T>, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    double d = 5.0;
+    mpz_class e;
+    e = a * (b + d) + c; ASSERT_ALWAYS(e == 20);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    double d = 5.0;
+    mpz_class e;
+    e = a * (b + d) - c; ASSERT_ALWAYS(e == 12);
+  }
+}
+
+static void
+check_mpz_21 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <__gmp_expr<mpz_t, T>, mpz_class, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    signed int d = 5;
+    mpz_class e;
+    e = (a - d) * b + c; ASSERT_ALWAYS(e == -5);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    signed int d = 5;
+    mpz_class e;
+    e = (a - d) * b - c; ASSERT_ALWAYS(e == -13);
+  }
+}
+
+static void
+check_mpz_22 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <__gmp_expr<mpz_t, T>, U, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3);
+    unsigned int c = 4, d = 5;
+    mpz_class e;
+    e = (a + c) * d + b; ASSERT_ALWAYS(e == 33);
+  }
+  {
+    mpz_class a(2), b(3);
+    unsigned int c = 4, d = 5;
+    mpz_class e;
+    e = (a + c) * d - b; ASSERT_ALWAYS(e == 27);
+  }
+}
+
+static void
+check_mpz_23 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <T, __gmp_expr<mpz_t, U>, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3);
+    double c = 4.0, d = 5.0;
+    mpz_class e;
+    e = c * (a + d) + b; ASSERT_ALWAYS(e == 31);
+  }
+  {
+    mpz_class a(2), b(3);
+    double c = 4.0, d = 5.0;
+    mpz_class e;
+    e = c * (a + d) - b; ASSERT_ALWAYS(e == 25);
+  }
+
+}
+
+static void
+check_mpz_24 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <__gmp_expr<mpz_t, T>, __gmp_expr<mpz_t, U>, Op1> >, mpz_class, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    signed int d = 5, e = 6;
+    mpz_class f;
+    f = (a - d) * (b + e) + c; ASSERT_ALWAYS(f == -23);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    signed int d = 5, e = 6;
+    mpz_class f;
+    f = (a - d) * (b + e) - c; ASSERT_ALWAYS(f == -31);
+  }
+}
+
+static void
+check_mpz_25 (void)
+{
+  // template <class T, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <mpz_class, mpz_class, Op1> >, __gmp_expr<mpz_t, T>, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    unsigned int d = 5;
+    mpz_class e;
+    e = a * b + (c - d); ASSERT_ALWAYS(e == 5);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    unsigned int d = 5;
+    mpz_class e;
+    e = a * b - (c - d); ASSERT_ALWAYS(e == 7);
+  }
+}
+
+static void
+check_mpz_26 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <mpz_class, T, Op1> >, __gmp_expr<mpz_t, U>, Op2> >
+  {
+    mpz_class a(2), b(3);
+    double c = 4.0, d = 5.0;
+    mpz_class e;
+    e = a * c + (b + d); ASSERT_ALWAYS(e == 16);
+  }
+  {
+    mpz_class a(2), b(3);
+    double c = 4.0, d = 5.0;
+    mpz_class e;
+    e = a * c - (b + d); ASSERT_ALWAYS(e == 0);
+  }
+}
+
+static void
+check_mpz_27 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <T, mpz_class, Op1> >, __gmp_expr<mpz_t, U>, Op2> >
+  {
+    mpz_class a(2), b(3);
+    signed int c = 4, d = 5;
+    mpz_class e;
+    e = c * a + (b - d); ASSERT_ALWAYS(e == 6);
+  }
+  {
+    mpz_class a(2), b(3);
+    signed int c = 4, d = 5;
+    mpz_class e;
+    e = c * a - (b - d); ASSERT_ALWAYS(e == 10);
+  }
+}
+
+static void
+check_mpz_28 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <mpz_class, __gmp_expr<mpz_t, T>, Op1> >, __gmp_expr<mpz_t, U>, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    unsigned int d = 5, e = 6;
+    mpz_class f;
+    f = a * (b - d) + (c + e); ASSERT_ALWAYS(f == 6);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    unsigned int d = 5, e = 6;
+    mpz_class f;
+    f = a * (b - d) - (c + e); ASSERT_ALWAYS(f == -14);
+  }
+}
+
+static void
+check_mpz_29 (void)
+{
+  // template <class T, class U, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <__gmp_expr<mpz_t, T>, mpz_class, Op1> >, __gmp_expr<mpz_t, U>, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    double d = 5.0, e = 6.0;
+    mpz_class f;
+    f = (a + d) * b + (c - e); ASSERT_ALWAYS(f == 19);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    double d = 5.0, e = 6.0;
+    mpz_class f;
+    f = (a + d) * b - (c - e); ASSERT_ALWAYS(f == 23);
+  }
+}
+
+static void
+check_mpz_30 (void)
+{
+  // template <class T, class U, class V, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <__gmp_expr<mpz_t, T>, U, Op1> >, __gmp_expr<mpz_t, V>, Op2> >
+  {
+    mpz_class a(2), b(3);
+    signed int c = 4, d = 5, e = 6;
+    mpz_class f;
+    f = (a + c) * d + (b + e); ASSERT_ALWAYS(f == 39);
+  }
+  {
+    mpz_class a(2), b(3);
+    signed int c = 4, d = 5, e = 6;
+    mpz_class f;
+    f = (a + c) * d - (b + e); ASSERT_ALWAYS(f == 21);
+  }
+}
+
+static void
+check_mpz_31 (void)
+{
+  // template <class T, class U, class V, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <T, __gmp_expr<mpz_t, U>, Op1> >, __gmp_expr<mpz_t, V>, Op2> >
+  {
+    mpz_class a(2), b(3);
+    unsigned int c = 4, d = 5, e = 6;
+    mpz_class f;
+    f = c * (a + d) + (b - e); ASSERT_ALWAYS(f == 25);
+  }
+  {
+    mpz_class a(2), b(3);
+    unsigned int c = 4, d = 5, e = 6;
+    mpz_class f;
+    f = c * (a + d) - (b - e); ASSERT_ALWAYS(f == 31);
+  }
+}
+
+static void
+check_mpz_32 (void)
+{
+  // template <class T, class U, class V, class Op1, class Op2>
+  // __gmp_expr<mpz_t, __gmp_binary_expr<__gmp_expr<mpz_t, __gmp_binary_expr
+  // <__gmp_expr<mpz_t, T>, __gmp_expr<mpz_t, U>, Op1> >,
+  // __gmp_expr<mpz_t, V>, Op2> >
+  {
+    mpz_class a(2), b(3), c(4);
+    double d = 5.0, e = 6.0, f = 7.0;
+    mpz_class g;
+    g = (a + d) * (b - e) + (c + f); ASSERT_ALWAYS(g == -10);
+  }
+  {
+    mpz_class a(2), b(3), c(4);
+    double d = 5.0, e = 6.0, f = 7.0;
+    mpz_class g;
+    g = (a + d) * (b - e) - (c + f); ASSERT_ALWAYS(g == -32);
+  }
+}
+
+void
+check_mpq (void)
+{
+  // currently there's no ternary mpq operation
+}
+
+void
+check_mpf (void)
+{
+  // currently there's no ternary mpf operation
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpz_1 ();
+  check_mpz_2 ();
+  check_mpz_3 ();
+  check_mpz_4 ();
+  check_mpz_5 ();
+  check_mpz_6 ();
+  check_mpz_7 ();
+  check_mpz_8 ();
+  check_mpz_9 ();
+  check_mpz_10 ();
+  check_mpz_11 ();
+  check_mpz_12 ();
+  check_mpz_13 ();
+  check_mpz_14 ();
+  check_mpz_15 ();
+  check_mpz_16 ();
+  check_mpz_17 ();
+  check_mpz_18 ();
+  check_mpz_19 ();
+  check_mpz_20 ();
+  check_mpz_21 ();
+  check_mpz_22 ();
+  check_mpz_23 ();
+  check_mpz_24 ();
+  check_mpz_25 ();
+  check_mpz_26 ();
+  check_mpz_27 ();
+  check_mpz_28 ();
+  check_mpz_29 ();
+  check_mpz_30 ();
+  check_mpz_31 ();
+  check_mpz_32 ();
+
+  check_mpq();
+  check_mpf();
+
+  tests_end();
+  return 0;
+}
diff --git a/third_party/gmp/tests/cxx/t-unary.cc b/third_party/gmp/tests/cxx/t-unary.cc
new file mode 100644
index 0000000..c7d8bf6
--- /dev/null
+++ b/third_party/gmp/tests/cxx/t-unary.cc
@@ -0,0 +1,132 @@
+/* Test mp*_class unary expressions.
+
+Copyright 2001-2003 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
+
+#include "config.h"
+
+#include <iostream>
+
+#include "gmpxx.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+using namespace std;
+
+
+void
+check_mpz (void)
+{
+  // template <class T, class Op>
+  // __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
+  {
+    mpz_class a(1);
+    mpz_class b(+a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpz_class a(2);
+    mpz_class b;
+    b = -a; ASSERT_ALWAYS(b == -2);
+  }
+  {
+    mpz_class a(3);
+    mpz_class b;
+    b = ~a; ASSERT_ALWAYS(b == -4);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
+  {
+    mpz_class a(1);
+    mpz_class b(-(-a)); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpz_class a(2);
+    mpz_class b;
+    b = -(-(-a)); ASSERT_ALWAYS(b == -2);
+  }
+}
+
+void
+check_mpq (void)
+{
+  // template <class T, class Op>
+  // __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
+  {
+    mpq_class a(1);
+    mpq_class b(+a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpq_class a(2);
+    mpq_class b;
+    b = -a; ASSERT_ALWAYS(b == -2);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
+  {
+    mpq_class a(1);
+    mpq_class b(-(-a)); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpq_class a(2);
+    mpq_class b;
+    b = -(-(-a)); ASSERT_ALWAYS(b == -2);
+  }
+}
+
+void
+check_mpf (void)
+{
+  // template <class T, class Op>
+  // __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> >
+  {
+    mpf_class a(1);
+    mpf_class b(+a); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpf_class a(2);
+    mpf_class b;
+    b = -a; ASSERT_ALWAYS(b == -2);
+  }
+
+  // template <class T, class U, class Op>
+  // __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
+  {
+    mpf_class a(1);
+    mpf_class b(-(-a)); ASSERT_ALWAYS(b == 1);
+  }
+  {
+    mpf_class a(2);
+    mpf_class b;
+    b = -(-(-a)); ASSERT_ALWAYS(b == -2);
+  }
+}
+
+
+int
+main (void)
+{
+  tests_start();
+
+  check_mpz();
+  check_mpq();
+  check_mpf();
+
+  tests_end();
+  return 0;
+}